设计模式-13-组合模式

组合模式是一种结构型设计模式, 使用它将对象组合成树状结构, 并且能像使用独立对象一样使用它们

逻辑结构

在组合模式中,有三个角色:

  • Component(抽象构件): 定义了叶子节点和组合节点的公共接口。
  • Leaf(叶子节点): 表示树形结构中的叶子节点对象,它没有子节点。
  • Composite(组合节点): 表示树形结构中的组合节点对象,它可以包含子节点
Component1

实现代码

代码路径:https://github.com/XBoom/DesignPatterns/tree/main/12_Component

  1. 定义抽象组件

    1
    2
    3
    4
    5
    6
    // 抽象构件
    type Component interface {
    Add(component Component)
    Remove(component Component)
    Display(depth int)
    }
  2. 叶子节点实现抽象组件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 叶子节点
    type Leaf struct {
    name string
    }

    func (l *Leaf) Add(component Component) {}

    func (l *Leaf) Remove(component Component) {}

    func (l *Leaf) Display(depth int) {
    fmt.Println(strings.Repeat("-", depth) + l.name)
    }
  3. 实现组合

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    // 组合节点
    type Composite struct {
    name string
    components []Component
    }

    func NewComposite(name string) *Composite {
    return &Composite{name, make([]Component, 0)}
    }

    func (c *Composite) Add(component Component) {
    c.components = append(c.components, component)
    }

    func (c *Composite) Remove(component Component) {
    for i, v := range c.components {
    if v == component {
    c.components = append(c.components[:i], c.components[i+1:]...)
    }
    }
    }

    func (c *Composite) Display(depth int) {
    fmt.Println(strings.Repeat("-", depth) + c.name)
    for _, component := range c.components {
    component.Display(depth + 2)
    }
    }

运行

1
2
3
4
5
6
7
8
9
10
11
root := NewComposite("root")
root.Add(&Leaf{"Leaf A"})
root.Add(&Leaf{"Leaf B"})

comp := NewComposite("Composite X")
comp.Add(&Leaf{"Leaf XA"})
comp.Add(&Leaf{"Leaf XB"})

root.Add(comp)

root.Display(1)

结果

1
2
3
4
5
6
-root
---Leaf A
---Leaf B
---Composite X
-----Leaf XA
-----Leaf XB

输出一个树形结构

总结

  • 可以利用多态和递归机制更方便地使用复杂树结构。
  • 开闭原则,无需更改现有代码, 就可以在应用中添加新元素, 使其成为对象树的一部分

参考链接

  1. https://refactoringguru.cn/design-patterns/composite
  2. https://lailin.xyz/post/composite.html