【Go-设计模式】组合模式 详解

概念:
组合模式(Composite Pattern),又叫 部分整体模式,
它创建了 对象组的树形结构,将 对象 组合成 树状结构 以表示 “整体-部分”的层次关系
这种类型的设计模式属于 结构型模式
组合模式使得用户对 单个对象 和 组合对象 的访问 具有一致性,
即:组合能让Client以 一致的方式 处理 个别对象 以及 组合对象

UML:

Component:
这是组合中对象声明接口,在适当情况下,实现 所有类共有的接口默认行为,用于 访问 和 管理
Component 子部件, Component 可以是 抽象类 或者 接口Leaf:
在组合中表示叶子节点,叶子节点没有子节点Composite:
非叶子节点, 用于存储子部件, 在 Component 接口中实现 子部件的相关操作,比如增加(add), 删除。
示例:
组件接口:
type Component interface {
Parent() Component
SetParent(Component)
Name() string
SetName(string)
AddChild(Component)
Print(string)
}
const (
LeafNode = iota
CompositeNode
)
func NewComponent(kind int, name string) Component {
var component Component
switch kind {
case LeafNode:
component = NewLeaf()
case CompositeNode:
component = NewComposite()
}
component.SetName(name)
return component
}
组件类:
type component struct {
parent Component
name string
}
func (this *component) Parent() Component {
return this.parent
}
func (this *component) SetParent(parent Component) {
this.parent = parent
}
func (this *component) Name() string {
return this.name
}
func (this *component) SetName(name string) {
this.name = name
}
func (this *component) AddChild(Component) {}
func (this *component) Print(string) {}
普通节点组件:
type Composite struct {
component
childs []Component
}
func NewComposite() *Composite {
return &Composite{
childs: make([]Component, 0),
}
}
func (this *Composite) AddChild(child Component) {
child.SetParent(this)
this.childs = append(this.childs, child)
}
func (this *Composite) Print(pre string) {
fmt.Printf("%s+%s\n", pre, this.Name())
pre += " "
for _, comp := range this.childs {
comp.Print(pre)
}
叶子节点组件:
type Leaf struct {
component
}
func NewLeaf() *Leaf {
return &Leaf{}
}
func (this *Leaf) Print(pre string) {
fmt.Printf("%s-%s\n", pre, this.Name())
}
测试:
package main
import (
"DemoProject/design/base23/composite" // 根据自己的项目路径定制
)
func main() {
// composite
root := composite.NewComponent(composite.CompositeNode, "root")
c1 := composite.NewComponent(composite.CompositeNode, "c1")
c2 := composite.NewComponent(composite.CompositeNode, "c2")
c3 := composite.NewComponent(composite.CompositeNode, "c3")
l1 := composite.NewComponent(composite.LeafNode, "l1")
l2 := composite.NewComponent(composite.LeafNode, "l2")
l3 := composite.NewComponent(composite.LeafNode, "l3")
root.AddChild(c1)
root.AddChild(c2)
c1.AddChild(c3)
c1.AddChild(l1)
c2.AddChild(l2)
c2.AddChild(l3)
root.Print("")
}
后记:
为什么在本次示例中,本人要创建 一个组件接口,一个组件类 呢?
这是因为,模拟了 抽象类
因为在Golang中,类与类之间,即使拥有继承关系,也不能通过实例创建来互相引用
如下段代码:
type A struct {
name string
age int
}
type B struct {
// 实现结构
A
address string
}

我们可以看到:
显示不能使用 B类实例,来充当 A类对象
因此,上文中就通过 接口 + 类 的形式,来模拟 “抽象类”
希望同学们能理解上文代码的细节

浙公网安备 33010602011771号