简介
组合模式将对象组合成树形结构,以表示“部分-整体”的层次结构。使得用户对单个对象的使用具有一致性
组合模式中的角色和职责
组件(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)
}
总结
优点
- 高层模块调用简单
- 节点自由增加
缺点
- 使用组合模式时,其叶子和树枝的声明都是实现类。而不是接口,违反了依赖倒置原则。
- 设计较复杂,客户端需要花更多时间理清类之间的层次关系;
- 不容易限制容器中的构件;
- 不容易用继承的方法来增加构件的新功能
适用场景
- 您想表示对象的部分-整体层次结构(树形结构)
- 您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。