组合模式_Go设计模式(组合模式)

组合模式(Composite)

定义

由于事物与事物之前存在某种关系,进而组织起来并形成某种结构并且可以共同发挥作用。组合模式又叫做"部分-整体"模式,它是一种将对象组合成树状的层次结构的模式,用来表示"部分-整体"的关系,使用户对单个对象和组合对象具有一致的访问性。

理解

桥接模式是指将不同的资源组合在一起构成丰富的功能。

例如:有一堆彩色的画笔和一堆各种形状的图案,通过两两组合(桥接),就可以形成不同色彩的图案。

60540c57b1bed73e8cd763bd9cac8e48.png

组合模式是将存在某种关系的相似资源组织起来,形成部分和整体有一致性的模式。

例如:如果仔细观察叶子会发现又有小的叶子,一个小的叶子上又有更小的枝叶。我们不管从宏观还是微观维度上看都是类似的结构。好似存在着某种大自然的规律,类似的结构总在重复、迭代地显现出某种自似性。(仔细观察下图片)

7d0298d1c568dae12b43b0ab31b4e4d8.png

代码

这其实牵扯到一个数学概念:分形理论。不管是连绵的山川、飘浮的云朵、岩石的断裂口、树冠、花菜、还是人类的大脑皮层……把这些部分与整体以某种方式相似的形体呈现出来就称为分形。从简单到复杂,或是复杂到简单,我们抽出任意一个“部分”,其与“整体”的结构是类似的。这里我们就拿类似树结构的文件系统目录结构来举例。

394b50ba3157aa3f12f1d32dab60b6f1.png

我们可以看到,从根目录开始,下面包含文件和文件夹,文件夹下面有包含子文件夹和子文件,而文件属于“叶子”节点,下面不再有延续分支。这里模糊文件和文件夹的区别,我们统一抽象为“节点”。

//Node 节点
type Node interface {
    //添加后续节点
    Add(child Node)
    //space 表示打印名字前,有几个空格
    Print(space int)
}

根据节点接口定义,实现文件类。文件类不能再添加后续节点,所以Add中什么也不做,Print负责打印文件名称,根据space决定打印名字前,控制几个空格。

type File struct {
    name string
}

//Add
func (t *File) Add(child Node) {
    //do nothing
}

//Print
func (t *File) Print(space int) {
    for i := 0; i         fmt.Print(" ")
    }
    fmt.Println(t.name)
}

根据接口定义,实现文件夹类。区别在于文件夹下,可以包含子文件和子文件夹,所以额外定义了child []Node 切片。Add负责追加Node节点到child中,Print负责打印名称,区别在于space传入下级目录的Print时,需要自增+1

type Folder struct {
    name  string
    child []Node
}

//Add add file or add folder
func (t *Folder) Add(child Node) {
    t.child = append(t.child, child)
}

//Print
func (t *Folder) Print(space int) {
    for i := 0; i         fmt.Print(" ")
    }
    fmt.Println(t.name)
    //传入下级目录
    space++
    for _, v := range t.child {
        v.Print(space)
    }
}

调用范例:

func main() {
    //根目录D盘
    diver := Folder{name: "D:"}
    //两个文件
    f1 := File{name: "1.txt"}
    f2 := File{name: "test.txt"}
    //文件夹
    fd1 := Folder{name: "文档"}
    ff1 := File{name: "2.txt"}
    ff2 := File{name: "3.txt"}
    ff3 := File{name: "4.txt"}
    fd1.Add(&ff1)
    fd1.Add(&ff2)
    fd1.Add(&ff3)
    //追加到D文件夹中
    diver.Add(&f1)
    diver.Add(&f2)
    diver.Add(&fd1)
    //打印目录层次
    diver.Print(0)
    return
}

输出:

c7f981d1f21bb4acb0248455e1c83101.png

可以看到组合模式,其实就是相似的资源(文件或文件夹)互相递归叠加,最后组成一个庞大的文件系统结构。再比如生物体,先从单细胞生物,到多细胞生物,再到高级生物,其部分(单个细胞)与整体(生命个体)结构或其行为总是以类似的形式涌现,分形之道如此,组合模式亦是如此。

源代码地址:

https://github.com/gofish2020/gopattern/tree/main/structure/composite

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值