全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

如何使用Golang实现组合模式_统一处理单个对象和组合对象

组合模式在Go中通过接口+嵌入+递归实现统一处理Leaf和Composite:定义Component接口,Leaf实现基础行为,Composite聚合子节点并递归委托,客户端透明调用无需类型判断。

组合模式(Composite Pattern)在 Go 语言中不依赖继承和抽象类,而是通过接口 + 嵌入(embedding)+ 递归结构来实现统一处理单个对象(Leaf)和组合对象(Composite)。核心是定义一个公共行为接口,让两者都实现它,从而在调用侧无需区分类型。

定义组件接口:统一操作契约

先定义一个 Component 接口,声明所有节点共有的行为,比如 Operation()GetPrice()Add(Component)(仅 Composite 需要,Leaf 可空实现或 panic):

  // Component 定义通用行为
type Component interface {
  Operation() string
  GetPrice() float64
}
  // Leaf 实现接口,不包含子节点
type Leaf struct {
  name string
  price float64
}
func (l Leaf) Operation() string { return "Leaf: " + l.name }
func (l Leaf) GetPrice() float64 { return l.price }

实现组合对象:聚合子节点并委托行为

Composite 结构体嵌入切片保存子 Component,并实现相同接口。关键在于:其方法内部递归调用子节点的同名方法,把“组合”逻辑封装在自身内:

  // Composite 持有多个 Component
type Composite struct {
  name string
  children []Component // 存储 interface 类型,支持 Leaf 和其他 Composite
}
func (c *Composite) Add(child Component) {
  c.children = append(c.children, child)
}
func (c *Composite) Operation() string {
  result := "Composite: " + c.name + "\n"
  for _, child := range c.children {
    result += "\t" + child.Operation() + "\n"
  }
  return result
}
func (c *Composite) GetPrice() float64 {
  sum := 0.0
  for _, child := range c.children {
    sum += child.GetPrice()
  }
  return sum
}

客户端透明使用:无需类型判断

调用方只依赖 Component 接口,无论是传入 Leaf 还是 *Composite,都能直接调用方法。递归结构自动展开,真正实现“统一处理”:

func main() {
  leaf1 := Leaf{name: "USB Cable", price: 12.5}
  leaf2 := Leaf{name: "Mouse", price: 49.9}

  subComp := &Composite{name: "Peripherals"}
  subComp.Add(leaf1)
  subComp.Add(leaf2)

  root := &Composite{name: "Desktop Setup"}
  root.Add(subComp)
  root.Add(Leaf{name: "Monitor", price: 299.0})

  fmt.Println(root.Operation())
  fmt.Printf("Total Price: $%.2f\n", root.GetPrice())
}
  // 输出自动包含层级缩进和总价,客户端无感知内部结构

注意事项与实用技巧

  • Go 没有“强制实现”机制,Leaf 不应实现 Add() 方法;若误调用,可在 Composite 的 Add 中加 nil 检查或 panic 提示
  • 为避免意外修改,Composite 的 children 切片建议不暴露为公开字段,只通过 Add() 等方法操作
  • 如需支持遍历(如深度优先),可额外添加 Iterator() Iterator 方法,返回自定义迭代器
  • 性能敏感场景下,避免频繁分配字符串;可用 strings.Builder 替代 += 拼接


# go  # golang  # app  # usb  # ai  # String  # for  # 封装  # printf  # 字符串  # 结构体  # 递归  # 继承  # 接口  # Struct  # Interface  # 委托  # 切片  # nil  # append  # 对象  # embedding  # 客户端  # 多个  # 都能  # 遍历  # 而在  # 可在  # 自定义  # 不应  # 如需 


相关文章: 如何在万网自助建站中设置域名及备案?  建站之星后台管理:高效配置与模板优化提升用户体验  兔展官网 在线制作,怎样制作微信请帖?  网站制作大概多少钱一个,做一个平台网站大概多少钱?  平台云上自助建站如何快速打造专业网站?  建站之星好吗?新手能否轻松上手建站?  免费视频制作网站,更新又快又好的免费电影网站?  建站OpenVZ教程与优化策略:配置指南与性能提升  如何在自有机房高效搭建专业网站?  阿里云网站搭建费用解析:服务器价格与建站成本优化指南  如何通过服务器快速搭建网站?完整步骤解析  网站海报制作教学视频教程,有什么免费的高清可商用图片网站,用于海报设计?  浅谈Javascript中的Label语句  企业宣传片制作网站有哪些,传媒公司怎么找企业宣传片项目?  头像制作网站在线制作软件,dw网页背景图像怎么设置?  大同网页,大同瑞慈医院官网?  网站制作的步骤包括,正确网址格式怎么写?  b2c电商网站制作流程,b2c水平综合的电商平台?  c# await 一个已经完成的Task会发生什么  视频网站app制作软件,有什么好的视频聊天网站或者软件?  已有域名如何免费搭建网站?  常州企业建站如何选择最佳模板?  已有域名建站全流程解析:网站搭建步骤与建站工具选择  如何撰写建站申请书?关键要点有哪些?  公司网站制作需要多少钱,找人做公司网站需要多少钱?  建站主机功能解析:服务器选择与快速搭建指南  微信小程序制作网站有哪些,微信小程序需要做网站吗?  网站微信制作软件,如何制作微信链接?  ,网页ppt怎么弄成自己的ppt?  如何选择高性价比服务器搭建个人网站?  nginx修改上传文件大小限制的方法  山东网站制作公司有哪些,山东大源集团官网?  免费ppt制作网站,有没有值得推荐的免费PPT网站?  如何通过VPS搭建网站快速盈利?  建站168自助建站系统:快速模板定制与SEO优化指南  洛阳网站制作公司有哪些,洛阳的招聘网站都有哪些?  早安海报制作网站推荐大全,企业早安海报怎么每天更换?  怀化网站制作公司,怀化新生儿上户网上办理流程?  平台云上自主建站:模板化设计与智能工具打造高效网站  如何在云主机快速搭建网站站点?  厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?  建站之星在线客服如何快速接入解答?  如何通过宝塔面板实现本地网站访问?  移动端手机网站制作软件,掌上时代,移动端网站的谷歌SEO该如何做?  详解jQuery停止动画——stop()方法的使用  宝塔新建站点为何无法访问?如何排查?  武汉网站制作费用多少,在武汉武昌,建面100平方左右的房子,想装暖气片,费用大概是多少啊?  如何快速生成凡客建站的专业级图册?  建站主机选哪家性价比最高?  公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。