• 组合模式:

  允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。

  组合模式适用于创建复杂的对象,这个对象包含某些个别的对象以及这些对象的组合。

  从操作的角度而言,客户端对于 个别对象/组合 的操作是一致的。

  • 模拟场景

  如图所示,总公司下属有多个部门,而子公司可以视为多个部门的组合。

  整个数据结构呈树状,完美契合组合模式的应用场景。

  • UML:

  在这个场景中:

  1. 个别对象 -> 人事部(HRDepartment)和财务部(FinanceDepartment)
  2. 个别对象的组合 -> 公司(Company)
  3. 无论是 Company 还是 Department,对于 Client 而言,都被当做 CompanyItem 使用。
  4. 从树形结构来理解,Department 是叶节点,Company 是非叶节点。
  • 代码:
@Data
@AllArgsConstructor
@ToString
public abstract class CompanyItem { protected String name; protected void addCompanyItem(CompanyItem companyItem) {
throw new UnsupportedOperationException("Not support to add companyItem");
} protected void removeCompanyItem(CompanyItem companyItem) {
throw new UnsupportedOperationException("Not support to remove companyItem");
} protected abstract void lineOfDuty(); protected abstract void showStructure(int depth);
}
public final class Company extends CompanyItem {

    private List<CompanyItem> childCompanyItems = new ArrayList<>();

    public Company(String name) {
super(name);
} @Override
public void addCompanyItem(CompanyItem component) {
childCompanyItems.add(component);
} @Override
public void removeCompanyItem(CompanyItem component) {
childCompanyItems.remove(component);
} @Override
public void lineOfDuty() {
childCompanyItems.forEach(companyItem -> companyItem.lineOfDuty());
} @Override
public void showStructure(int depth) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < depth; ++i) {
builder.append("-");
}
System.out.println(builder.append(name));
childCompanyItems.forEach(companyItem -> companyItem.showStructure(depth + 1));
}
}
public final class FinanceDepartment extends CompanyItem {

    public FinanceDepartment(String name) {
super(name);
} @Override
public void lineOfDuty() {
System.out.println(name + ", treasurer is in charge of payroll");
} @Override
public void showStructure(int depth) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < depth; ++i) {
builder.append("-");
}
System.out.println(builder.append(name));
}
}
public final class HRDepartment extends CompanyItem {

    public HRDepartment(String name) {
super(name);
} @Override
public void lineOfDuty() {
System.out.println(name + ", HR is responsible for recruiting new employees");
} @Override
public void showStructure(int depth) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < depth; ++i) {
builder.append("-");
}
System.out.println(builder.append(name));
}
}
  • 客户端调用:
    private CompanyItem createParentCompany() {
CompanyItem parentCompany = new Company("Shanghai parent company");
parentCompany.addCompanyItem(new HRDepartment("Parent company HR department"));
CompanyItem southChildCompany = new Company("South child company");
southChildCompany.addCompanyItem(new HRDepartment("South child company HR department"));
parentCompany.addCompanyItem(southChildCompany);
CompanyItem hongKongOffice = new Company("HongKong office");
hongKongOffice.addCompanyItem(new FinanceDepartment("Hongkong office Finance department"));
southChildCompany.addCompanyItem(hongKongOffice);
parentCompany.addCompanyItem(new FinanceDepartment("Parent company Finance department"));
return parentCompany;
} @Test
void testComposite() {
CompanyItem parentCompany = createParentCompany();
parentCompany.showStructure(1);
System.out.println("===========================");
parentCompany.lineOfDuty();
}
  • 输出:

设计模式(八)组合模式 Composite的更多相关文章

  1. 乐在其中设计模式(C#) - 组合模式(Composite Pattern)

    原文:乐在其中设计模式(C#) - 组合模式(Composite Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 组合模式(Composite Pattern) 作者:weba ...

  2. 【设计模式】组合模式 Composite Pattern

    树形结构是软件行业很常见的一种结构,几乎随处可见,  比如: HTML 页面中的DOM,产品的分类,通常一些应用或网站的菜单,Windows Form 中的控件继承关系,Android中的View继承 ...

  3. 二十四种设计模式:组合模式(Composite Pattern)

    组合模式(Composite Pattern) 介绍将对象组合成树形结构以表示"部分-整体"的层次结构.它使得客户对单个对象和复合对象的使用具有一致性.示例有一个Message实体 ...

  4. [设计模式] 8 组合模式 Composite

    DP书上给出的定义:将对象组合成树形结构以表示“部分-整体”的层次结构.组合使得用户对单个对象和组合对象的使用具有一致性.注意两个字“树形”.这种树形结构在现实生活中随处可见,比如一个集团公司,它有一 ...

  5. python 设计模式之组合模式Composite Pattern

    #引入一 文件夹对我们来说很熟悉,文件夹里面可以包含文件夹,也可以包含文件. 那么文件夹是个容器,文件夹里面的文件夹也是个容器,文件夹里面的文件是对象. 这是一个树形结构 咱们生活工作中常用的一种结构 ...

  6. 设计模式-12组合模式(Composite Pattern)

    1.模式动机 很多时候会存在"部分-整体"的关系,例如:大学中的部门与学院.总公司中的部门与分公司.学习用品中的书与书包.在软件开发中也是这样,例如,文件系统中的文件与文件夹.窗体 ...

  7. 设计模式 笔记 组合模式 Composite

    //---------------------------15/04/16---------------------------- //Composite 组合模式----对象结构型模式 /* 1:意 ...

  8. 【设计模式】—— 组合模式Composite

    前言:[模式总览]——————————by xingoo 模式意图 使对象组合成树形的结构.使用户对单个对象和组合对象的使用具有一致性. 应用场景 1 表示对象的 部分-整体 层次结构 2 忽略组合对 ...

  9. 结构型设计模式之组合模式(Composite)

    结构 意图 将对象组合成树形结构以表示“部分-整体”的层次结构.C o m p o s i t e 使得用户对单个对象和组合对象的使用具有一致性. 适用性 你想表示对象的部分-整体层次结构. 你希望用 ...

  10. 设计模式之组合模式(Composite)

    组合模式原理:组合模式的作用是讲继承同一父类的不同子类对象组合起来,形成一个树形的结构,例如公司的部门组织 代码如下 #include <iostream> #include <st ...

随机推荐

  1. 洛谷 P2176 [USACO14FEB]路障Roadblock

    题目描述 每天早晨,FJ从家中穿过农场走到牛棚.农场由 N 块农田组成,农田通过 M 条双向道路连接,每条路有一定长度.FJ 的房子在 1 号田,牛棚在 N 号田.没有两块田被多条道路连接,以适当的路 ...

  2. Windows服务管理

    按键:win+R 输入:services.msc “服务和应用程序”界面选项打开 * sc命令的使用:create(创建) delete(删除)等 * service可执行文件路径的修改:win+R ...

  3. 使用ServiceController组件控制计算机服务

    实现效果: 知识运用: ServiceController组件的MachineName属性 //获取或设置服务所驻留的计算机名称 public string MachineName{get;set;} ...

  4. python_97_类的继承2

    # 经典类与新式类差别主要体现在多继承上 #多继承是从左到有 class People():#经典类 #class People(object):#新式类 def __init__(self,name ...

  5. 变量和数据类型&运算符

    变量和数据类型&运算符 变量 变量的作用:用来存储数据 变量命名的规范:字(字符串)下(_下划线)美($)人(¥) 数 (可以包括数字)骆驼 有意义(可以以字母,下划线,美元符号,人民币符号开 ...

  6. c++ 创建路径方法

    linux.unix平台 #include "stdio.h" #include "stdlib.h" #include <sys/types.h> ...

  7. Repeat a string repeat a string-freecodecamp算法题目

    Repeat a string repeat a string(重复输出字符串) 要求 重复一个指定的字符串 num次 如果num是一个负数则返回一个空字符串. 思路 将给定的字符串赋给定义的变量te ...

  8. 字节跳动后端开发实习生面试(Python)

    一面: 1.自我介绍. 2.介绍“工大小美”项目相关. 3.Python中的GIL(全局解释器锁),以及哪种情况下使用python的多线程性能有较大的提升. 4.项目中用到了SQLite数据库,如果有 ...

  9. PAT 乙级 1088

    题目 题目链接:PAT 乙级 1088 题解 比较简单的一道题,下面来简单说说思路: 因为甲确定是一个两位数,因此通过简单的暴力循环求解甲的值,又根据题设条件“把甲的能力值的 2 个数字调换位置就是乙 ...

  10. 10GNU C语言函数调用

    6. C 函数调用机制概述 ​ 在 Linux 内核程序 boot/head.s 执行完基本初始化操作之后,就会跳转区执行 init/main.c 程序.那么 head.s 程序时如何把执行控制转交给 ...