组合模式

定义

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

组合模式,将一组对象组织成树形结构,将单个对象和组合对象都看做树中的节点,以统一处理逻辑,并且它利用树形结构的特点,递归地处理每个子树,依次简化代码实现。使用组合模式的前提在于,你的业务场景必须能够表示成树形结构。所以,组合模式的应用场景也比较局限,它并不是一种很常用的设计模式。

适用范围

1、您想表示对象的部分-整体层次结构(树形结构);

2、您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

优点

1、高层模块调用简单;

2、节点自由增加。

缺点

1、设计较复杂,客户端需要花更多时间理清类之间的层次关系;

2、不容易限制容器中的构件;

3、不容易用继承的方法来增加构件的新功能;

代码实现

公司有部门,部门下面有员工,使用组合模式来表示这种层次关系。

type Employee struct {
no int
name string
dept string
salary int
subordinates []*Employee
} func NewEmployee(no int, name, dept string, salary int) *Employee {
return &Employee{
no: no,
name: name,
dept: dept,
salary: salary,
subordinates: []*Employee{},
}
} func (e *Employee) add(em *Employee) {
e.subordinates = append(e.subordinates, em)
} func (e *Employee) remove(em *Employee) {
for index, item := range e.subordinates {
if item.no == em.no {
e.subordinates = e.subordinates[:index+copy(e.subordinates[index:], e.subordinates[index+1:])]
break
}
}
} func (e *Employee) getSubordinates() []*Employee {
return e.subordinates
} func (e *Employee) toString() {
fmt.Println(fmt.Sprintf("Employee:no:%d;name:%s;dept:%s;salary:%d。", e.no, e.name, e.dept, e.salary))
}

测试文件

func TestComposite(t *testing.T) {
ceo := NewEmployee(1, "马云", "CEO", 1000000) headMarketing := NewEmployee(2, "小白", "市场总监", 50000)
clerk1 := NewEmployee(1001, "小明", "Marketing", 10000)
clerk2 := NewEmployee(1002, "小张", "Marketing", 10000) cto := NewEmployee(3, "小龙", "CTO", 90000)
tc1 := NewEmployee(1003, "马龙", "Technology", 10000)
tc2 := NewEmployee(1004, "张龙", "Technology", 10000) ceo.add(headMarketing)
headMarketing.add(clerk1)
headMarketing.add(clerk2) ceo.add(cto)
cto.add(tc1)
cto.add(tc2) ceo.toString()
for _, subordinate := range ceo.subordinates {
fmt.Println("部门", "+++++++++++++++")
subordinate.toString()
for _, employee := range subordinate.subordinates {
employee.toString()
}
}
}

结构图

参考

【文中代码】https://github.com/boilingfrog/design-pattern-learning/tree/master/组合模式

【大话设计模式】https://book.douban.com/subject/2334288/

【极客时间】https://time.geekbang.org/column/intro/100039001

【菜鸟教程】https://www.runoob.com/design-pattern/composite-pattern.html

【原文地址】https://boilingfrog.github.io/2021/11/16/使用go实现组合模式/

设计模式学习-使用go实现组合模式的更多相关文章

  1. C#设计模式学习笔记:(9)组合模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7743118.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲结构型设计模式的第四个模式--组 ...

  2. .NET设计模式(11):组合模式(Composite Pattern)(转)

    概述 组合模式有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦. 意图 将对 ...

  3. Java 设计模式系列(九)组合模式

    Java 设计模式系列(九)组合模式 将对象组合成树形结构以表示"部分-整体"的层次结构.组合模式使得用户对单个对象的使用具有一致性. 一.组合模式结构 Component: 抽象 ...

  4. 设计模式之第22章-组合模式(Java实现)

    设计模式之第22章-组合模式(Java实现) “鱼哥,有没有什么模式是用来处理树形的“部分与整体”的层次结构的啊.”“当然”“没有?”“有啊.别急,一会人就到了.” 组合模式之自我介绍 “请问你是?怎 ...

  5. 【设计模式】学习笔记13:组合模式(Composite)

    本文出自   http://blog.csdn.net/shuangde800 认识组合模式 上一篇中,我们可以用迭代器来实现遍历一个集合(数组,ArrayList, Vector, HashTabl ...

  6. Java设计模式学习笔记(四) 抽象工厂模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 抽象工厂模式概述 工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问 ...

  7. 设计模式(C#)——08组合模式

    推荐阅读:  我的CSDN  我的博客园  QQ群:704621321       游戏通常包含许多视图.主视图中显示角色.有一个子视图,显示玩家的积分.有一个子视图,显示游戏中剩下的时间.      ...

  8. 【设计模式】结构型05组合模式(Composite Pattern)

    组合模式(Composite Pattern) 意图:将对象组合成树形结构以表示"部分-整体"的层次结构.组合模式使得用户对单个对象和组合对象的使用具有一致性. 主要解决:它在我们 ...

  9. Java设计模式学习笔记(二) 简单工厂模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 正文开始... 1. 简介 简单工厂模式不属于GoF23中设计模式之一,但在软件开发中应用也较为 ...

  10. Java设计模式学习笔记(三) 工厂方法模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 简介 上一篇博客介绍了简单工厂模式,简单工厂模式存在一个很严重的问题: 就是当系统需要引入 ...

随机推荐

  1. Kubernetes(K8S) 镜像拉取策略 imagePullPolicy

    镜像仓库,镜像已更新,版本没更新, K8S 拉取后,还是早的服务,原因:imagePullPolicy 镜像拉取策略 默认为本地有了就不拉取,需要修改 [root@k8smaster ~]# kube ...

  2. flask 上传文件,视图

    记得有template ''' 导入flask类.该类的实例将会成为我们的wsgi应用 __name__是一个适用于大多数情况的快捷方式,有了这个参数,flask才能知道在那里找到模板和静态文件等东西 ...

  3. VS遇到 error C4996问题的解决方法

    在编译c++程序时报如下错: error C4996: 'strncat': This function or variable may be unsafe. Consider using strnc ...

  4. Codeforces Round #617 (Div. 3) A~E

    比赛链接:Here 1296A. Array with Odd Sum 题意:给了 \(n\) 个数,现在就是说可以选择两个数让其中一个的值等于另一个的值. 这种操作无限次 问是不是能让这n个数操作后 ...

  5. 【数据库】E-R图向关系模型转换的规则

    E-R图向关系模型转换的规则: (1) 一个实体型转换为一个关系模式,实体的属性就是关系的属性,实体的码(关键字)就是关系的码. (2) 一个 1:1 联系可以转换为一个独立的关系模式,也可以与任意一 ...

  6. LocalDateTime、LocalDate、Date的相互转换

    1==LocalDateTime 转 LocalDate: 直接调用 toLocalDate() 方法: LocalDateTime localDateTime = LocalDateTime.now ...

  7. mongodb导入本地json文件

  8. 每天学五分钟 Liunx 111 | 存储篇:NFS

    NFS NFS(Network File System,网络文件系统),它可以通过网络让不同操作系统,不同机器共享彼此的文件. NFS 分为服务端和客户端.服务端提供共享的文件目录,客户端将该目录挂载 ...

  9. spring--JDK动态代理和CGLIB代理的区别

    JDK 动态代理和 CGLIB 代理是 Java 中常用的两种动态代理实现方式,它们各有特点和适用场景: JDK 动态代理: JDK 动态代理是基于接口的代理方式,它使用 Java 反射机制来创建代理 ...

  10. ABP微服务系列学习-微服务模板结构

    开源版本ABP CLI里面的模板是不包含微服务模板的,而商业版里面有一个微服务模板.这个模板据说是微服务的最佳实践,eShopOnAbp这个仓库的结构基本也和商业版的微服务模板一致.那就开始学习一下. ...