一、组合模式基本介绍:
- ①:组合模式
(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示“整体-部分”的层次关系。 - ②:组合模式依据树形结构来组合对象,用来表示部分、整体的层次。
- ③:这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。
- ④:这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。
- ⑤:组合模式使得用户对单个对象和组合对象的访问具有一致性。及:组合能让客户以一致的方式处理个别对象以及组合对象。
二、组合模式解决的问题:
组合模式解决这样的问题,当我们要处理的对象可以生成一颗树形结构,而我们要对树上的节点和叶子节点进行操作时。它能够提供一致的方式,而不用考虑它是节点还是叶子节点。
- ①:你想表示对象的部分-整体层次结构(树形结构)。
- ②:您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
- ③:部分、整体场景。如树形菜单,文件、文件夹、公司、部门等的管理。
三、组合模式结构图
组件(Component)类是组合类(Composite)和叶子类(Leaf)的父类,可以把组合类看成是树的中间节点。
组合对象拥有一个或者多个组件对象,因此组合对象的操作可以委托给组件对象去处理,而组件对象可以是另一个组合对象或者叶子对象。
四、具体案例:

Company公司类,抽象类 或 接口
public abstract class Company {public String name;public Company(String name) {this.name = name;}/*牺牲透明性换取单一职责原则,这样就不用考虑是叶子节点还是组合节点*/public void add(Company company) {throw new UnsupportedOperationException();}/*牺牲透明性换取单一职责原则,这样就不用考虑是叶子节点还是组合节点*/public void remove(Company company) {throw new UnsupportedOperationException();}/*** 职责范围*/public void lineOfDuty() {lineOfDuty(0);}public abstract void lineOfDuty(int depth);}
ConcreteCompany具体公司类,实现Company接口,是非叶子节点。
public class ConcreteCompany extends Company {private List<Company> childList = new LinkedList<>();public ConcreteCompany(String name) {super(name);}@Overridepublic void add(Company company) {childList.add(company);}@Overridepublic void remove(Company company) {childList.remove(company);}@Overridepublic void lineOfDuty(int depth) {for (int i = 0; i < depth; i++) {System.out.print("----");}System.out.println("Composite: " + name);for (Company child : childList) {child.lineOfDuty(depth + 1);}}}
HRDepartment人力资源部门类,实现Company接口,是叶子节点。
public class HRDepartment extends Company {public HRDepartment(String name) {super(name);}@Overridepublic void lineOfDuty(int depth) {for (int i = 0; i < depth; i++) {System.out.print("----");}System.out.println("left: " + name);}}
FinanceDepartment财务部门类,实现Company接口,是叶子节点。
问题:为什么叶子节点有
HRDepartment人力资源部门、FinanceDepartment财务部门 两个具体类。 理由:因为HRDepartment人力资源部门、FinanceDepartment财务部门 真实的业务中,各自执行的业务不同。举一反三
public class FinanceDepartment extends Company {public FinanceDepartment(String name) {super(name);}@Overridepublic void lineOfDuty(int depth) {for (int i = 0; i < depth; i++) {System.out.print("----");}System.out.println("left: " + name);}}
客户端调用
public class Client {public static void main(String[] args) {Company root = new ConcreteCompany("北京公司总部");root.add(new HRDepartment("人力资源部"));root.add(new FinanceDepartment("财务部"));Company root_sub_HuaDong = new ConcreteCompany("上海华东分公司");root.add(root_sub_HuaDong);root_sub_HuaDong.add(new HRDepartment("人力资源部"));root_sub_HuaDong.add(new FinanceDepartment("财务部"));Company root_sub_HuaDong_NanJing = new ConcreteCompany("南京办事处");root_sub_HuaDong.add(root_sub_HuaDong_NanJing);root_sub_HuaDong_NanJing.add(new HRDepartment("人力资源部"));root_sub_HuaDong_NanJing.add(new FinanceDepartment("财务部"));Company root_sub_HuaDong_HangZhou = new ConcreteCompany("杭州办事处");root_sub_HuaDong.add(root_sub_HuaDong_HangZhou);root_sub_HuaDong_HangZhou.add(new HRDepartment("人力资源部"));root_sub_HuaDong_HangZhou.add(new FinanceDepartment("财务部"));root.lineOfDuty();}}
输出内容:
Composite: 北京公司总部----left: 人力资源部----left: 财务部----Composite: 上海华东分公司--------left: 人力资源部--------left: 财务部--------Composite: 南京办事处------------left: 人力资源部------------left: 财务部--------Composite: 杭州办事处------------left: 人力资源部------------left: 财务部
