设计模式之组合模式

一、什么是组合模式

组合模式,它是一种将对象组合成树状的层次结构的模式,用来表示“整体-部分”的关系,使用户对单个对象和组合对象具有一致的访问性。

组合模式,又叫作整体-部分模式,属于结构型设计模式。

设计模式之组合模式插图

二、组合模式类图

设计模式之组合模式插图2

三、组合模式角色

  • 抽象组件角色(Component): 作为树枝节点和树叶节点的公共抽象类,并提供它们方法的默认实现。
  • 树枝节点角色(Composite): 树枝节点继承Component,存在子节点,组合树枝节点和叶子节点形成一个树形结构。
  • 叶子节点角色(Leaf): 叶子节点没有子节点,是树形结构中最小单位。

四、组合模式优缺点

1、优点

  1. 简化客户端代码:组合模式使得客户端代码可以一致地处理单个对象和组合对象,无需关心自己处理的是单个对象还是组合对象。
  2. 符合开闭原则:更容易在组合体内加入新的对象,客户端不会因为加入了新的对象而更改源代码。

2、缺点

  1. 设计相对复杂:客户端需要花费更多时间理清类之间的层次关系。
  2. 不容易限制容器中的构件。
  3. 不容易用继承的方式来增加构件的新功能。

五、组合模式demo示例

1、Demo需求

使用组合模式,展示集团公司组织结构层次,公司组织架构包括:集团->分公司->部门。

UML类图如下:

设计模式之组合模式插图4

2、抽象组件

/**
  * @Description: 抽象公司组件
  **/ public abstract class Enterprise {
     // 名称
     private String name;
     // 描述
     private String desc;
 
     public Enterprise(String name, String desc) {
         this.name = name;
         this.desc = desc;
     }
 
     protected void add(Enterprise c) {
         throw new UnsupportedOperationException();
     }
 
     protected void remove(Enterprise c) {
         throw new UnsupportedOperationException();
     }
 
     protected Enterprise get(int idx) {
         throw new UnsupportedOperationException();
     }
 
     protected abstract void show();
 
     public String getName() {
         return name;
     }
 
     public void setName(String name) {
         this.name = name;
     }
 
     public String getDesc() {
         return desc;
     }
 
     public void setDesc(String desc) {
         this.desc = desc;
     }
 }

3、具体化对象类

/**
  * @Description: 集团组织
  **/ public class Bloc extends Enterprise {
     private List<Enterprise> companies = new ArrayList<>();
 
     public Bloc(String name, String desc) {
         super(name, desc);
     }
 
     @Override
     protected void add(Enterprise c) {
         companies.add(c);
     }
 
     @Override
     protected void remove(Enterprise c) {
         companies.remove(c);
     }
 
     @Override
     protected Enterprise get(int idx) {
         return companies.get(idx);
     }
 
     @Override
     protected void show() {
         System.out.println("=======================================");
         System.out.println("集团:" + getName() + ", 描述:" + getDesc());
         companies.forEach(c -> {
             c.show();
         });
         System.out.println("=======================================");
     }
 }
/**
  * @Description: 分公司组织
  **/ public class BranchOfficer extends Enterprise {
     private List<Enterprise> officers = new ArrayList<>();
 
     public BranchOfficer(String name, String desc) {
         super(name, desc);
     }
 
     @Override
     protected void add(Enterprise c) {
         officers.add(c);
     }
 
     @Override
     protected void remove(Enterprise c) {
         officers.remove(c);
     }
 
     @Override
     protected Enterprise get(int idx) {
         return officers.get(idx);
     }
 
     @Override
     protected void show() {
         System.out.println("=======================================");
         System.out.println("--分公司:" + getName() + ", 描述:" + getDesc());
         officers.forEach(c -> {
             c.show();
         });
         System.out.println("=======================================");
     }
 }
/**
  * @Description: 部门组织
  **/ public class Department extends Enterprise {
     private List<Enterprise> departs = new ArrayList<>();
 
     public Department(String name, String desc) {
         super(name, desc);
     }
 
     @Override
     protected void add(Enterprise c) {
         departs.add(c);
     }
 
     @Override
     protected void remove(Enterprise c) {
         departs.remove(c);
     }
 
     @Override
     protected Enterprise get(int idx) {
         return departs.get(idx);
     }
 
     @Override
     protected void show() {
         System.out.println("=======================================");
         System.out.println("----部门:" + getName() + ", 描述:" + getDesc());
         departs.forEach(c -> {
             c.show();
         });
     }
 }

4、测试

/**
  * @Description: 组合模式客户端测试
  **/ public class Client {
     public static void main(String[] args) {
         Bloc xiaomiBloc = new Bloc("小米集团", "手机生产厂商");
 
         BranchOfficer xiaomiCompany1 = new BranchOfficer("小米上海分公司", "分公司");
         BranchOfficer xiaomiCompany2 = new BranchOfficer("小米北京公司", "母公司");
 
         Department xiaomiDepart1 = new Department("人事部", "绩效考核");
         Department xiaomiDepart2 = new Department("财务部", "发工资");
         Department xiaomiDepart3 = new Department("技术部", "开发MIUI系统");
         xiaomiCompany1.add(xiaomiDepart1);
         xiaomiCompany1.add(xiaomiDepart2);
         xiaomiCompany1.add(xiaomiDepart3);
         xiaomiCompany2.add(xiaomiDepart1);
         xiaomiCompany2.add(xiaomiDepart2);
         xiaomiCompany2.add(xiaomiDepart3);
 
         xiaomiBloc.add(xiaomiCompany1);
         xiaomiBloc.add(xiaomiCompany2);
 
         xiaomiBloc.show();
     }
 }
=======================================
集团:小米集团, 描述:手机生产厂商
=======================================
--分公司:小米上海分公司, 描述:分公司
=======================================
----部门:人事部, 描述:绩效考核
=======================================
----部门:财务部, 描述:发工资
=======================================
----部门:技术部, 描述:开发MIUI系统
=======================================
=======================================
--分公司:小米北京公司, 描述:母公司
=======================================
----部门:人事部, 描述:绩效考核
=======================================
----部门:财务部, 描述:发工资
=======================================
----部门:技术部, 描述:开发MIUI系统
=======================================
=======================================

发表评论