为了账号安全,请及时绑定邮箱和手机立即绑定

在 Golang 中使用组合的正确方法是什么

在 Golang 中使用组合的正确方法是什么

Go
开心每一天1111 2022-10-17 10:16:49
我是 OOP 人,最近我必须在 Golang 上工作,这是我以前没有做过的语言。虽然我已经阅读了很多关于组合的文章,但我注意到在 Golang 上正确使用它有点棘手假设我有两个 Golang 组合的例子,我不知道哪个是正确的,它们之间会有所不同吗?谢谢第一个例子type BaseClass struct {   db *DB}func NewBaseClass(db *DB) *BaseClass {  return &BaseClass{db}}type ChildrenClass1 struct {     baseClass *BaseClass}func NewChildrenClass1(db *DB) *ChildrenClass1 {  baseClass := NewBaseClass(db)  return &ChildrenClass1{baseClass}}type ChildrenClass2 struct {     baseClass *BaseClass}func NewChildrenClass2(db *DB) *ChildrenClass2 {  baseClass := NewBaseClass(db)  return &ChildrenClass2{baseClass}}func main(){  db := NewDB()  chilrend1 := NewChildrenClass1(db)  chilrend2 := NewChildrenClass2(db)}第二个例子type BaseClass struct {   db *DB}func NewBaseClass(db *DB) *BaseClass {  return &BaseClass{db}}type ChildrenClass1 struct {     baseClass *BaseClass}func NewChildrenClass1(baseClass *BaseClass) *ChildrenClass1 {  return &ChildrenClass1{baseClass}}type ChildrenClass2 struct {     baseClass *BaseClass}func NewChildrenClass2(baseClass *BaseClass) *ChildrenClass2 {  return &ChildrenClass2{baseClass}}func main(){  db := NewDB()  baseClass := NewBaseClass(db)  chilrend1 := NewChildrenClass1(baseClass)  chilrend2 := NewChildrenClass2(baseClass)}
查看完整描述

1 回答

?
LEATH

TA贡献1936条经验 获得超6个赞

在 Go中,您可能找不到像在许多其他基于 OOP 的语言中那样定义组合或聚合的正确方法。这只是因为Go 没有类,没有对象,没有异常,也没有模板。

但是 Go 有结构。结构是用户定义的类型。结构类型(带有方法)的用途与其他语言中的类类似。

说了这么多,让我们看看一些常见的定义,看看我们能做什么:

组合意味着孩子不能独立于父母而存在的关系。示例:房屋(父)和房间(子)。房间不存在独立于房屋[ 1 ]。

另一方面,聚合意味着孩子可以独立于父母而存在的关系。示例:教室(家长)和学生(孩子)。删除教室,学生仍然存在[ 1 ]。

因此,在聚合和组合中,“实例”“拥有”另一种类型的对象。但是有一个微妙的区别:聚合意味着子可以独立于父而存在的关系。组合意味着孩子不能独立于父母而存在的关系。

到目前为止,这就是我们现在从composition中所知道的:

  • 没有父母,孩子就无法存在

  • 组合是指将更简单的类型组合成更复杂的类型

  • 当然,我们主要使用它来重用代码

回答您的问题: 两者看起来都正确,但是,

  • 第一个例子更接近于composition,因为没有父母,孩子就不会存在;

  • 第二个例子更像是一个聚合,因为如果你删除父级,子级将保持存在。

我重写了您的代码以尝试举例说明:

第一个例子重写

package main


//Lamp struct is here to suppress the *DB that was in the original example

type Lamp struct {}


type Room struct {

    Lamps *[]Lamp

}



func NewRoom(l *[]Lamp) *Room {

  return &Room{l}

}


type House1 struct {

    Room *Room

}


func NewHouse1(l *[]Lamp) *House1 {

  r := NewRoom(l)

  return &House1{r}

}


type House2 struct {

    Room *Room

}


func NewHouse2(l *[]Lamp) *House2 {

  r := NewRoom(l)

  return &House2{r}

}


func main(){

  lamps := []Lamp{}

  house1 := NewHouse1(&lamps)

  house2 := NewHouse2(&lamps)

}

第二个例子重写:


package main


type LibraryCard struct {}


type Student struct {

   LibCard *LibraryCard

}


func NewStudent(l *LibraryCard) *Student {

  return &Student{l}

}


type Classroom1 struct {

    Student *Student

}


func NewClassroom1(s *Student) *Classroom1 {

  return &Classroom1{s}

}


type Classroom2 struct {

    Student *Student

}


func NewClassroom2(s *Student) *Classroom2 {

  return &Classroom2{s}

}


func main(){

  lc := new(LibraryCard)

  student := NewStudent(lc)

  classroom1 := NewClassroom1(student)

  classroom2 := NewClassroom2(student)

}


查看完整回答
反对 回复 2022-10-17
  • 1 回答
  • 0 关注
  • 106 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信