Skip to content

简介

组合模式将对象组合成树形结构,以表示“部分-整体”的层次结构。使得用户对单个对象的使用具有一致性

组合模式中的角色和职责

组件(Component)

一个接口,定义了组装体和叶子对象的共同操作

组装体(Composite)

Component接口的实现,包含了一组子组件

叶子(Leaf)

树结构中最基础的对象,也实现了Component接口

代码

以文件系统为例

package main

import "fmt"

const Separator = "--"


type FileSystemNode interface {
    Display(separator string)
}


type FileCommonFunc struct {
    fileName string
}


func (f *FileCommonFunc) SetFileName(fileName string) {
    f.fileName = fileName
}


type FileNode struct {
    FileCommonFunc
}


func (f *FileNode) Display(separator string) {
    fmt.Println(separator + f.fileName + "  文件内容为:Hello,world")
}


type DirectoryNode struct {
    FileCommonFunc
    nodes []FileSystemNode
}


func (d *DirectoryNode) Display(separator string) {
    fmt.Println(separator + d.fileName)
    for _, node := range d.nodes {
    node.Display(separator + Separator)
    }
}


func (d *DirectoryNode) Add(f FileSystemNode) {
    d.nodes = append(d.nodes, f)
}
func main() {
    //初始化
    biji := DirectoryNode{}
    biji.SetFileName("笔记")

    huiyi := DirectoryNode{}
    huiyi.SetFileName("会议")

    chenhui := FileNode{}
    chenhui.SetFileName("晨会.md")

    zhouhui := FileNode{}
    zhouhui.SetFileName("周会.md")
    //组装
    biji.Add(&huiyi)
    huiyi.Add(&chenhui)
    huiyi.Add(&zhouhui)
    //显示
    biji.Display(Separator)
}

总结

优点

  1. 高层模块调用简单
  2. 节点自由增加

缺点

  1. 使用组合模式时,其叶子和树枝的声明都是实现类。而不是接口,违反了依赖倒置原则。
  2. 设计较复杂,客户端需要花更多时间理清类之间的层次关系;
  3. 不容易限制容器中的构件;
  4. 不容易用继承的方法来增加构件的新功能

适用场景

  1. 您想表示对象的部分-整体层次结构(树形结构)
  2. 您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。