设计模式|组合模式--部分整体一致对待

1)概述
组合模式也称为合成模式、部分-整体模式(Part-Whole),主要是用来描述部分与整体关系。组合模式将对象组合成树形结构以表示”部分-整体”的层次结构,可以使客户端把一个个单独的成分对象和由它们复合而成的组合对象同等看待。
相似场景
1.家兴表哥开了一家公司饿了么,刚开始的时候就只有一家公司,他表哥让家兴给他开发了一套OA系统,后来随着公司的扩展变大,不断的在其它地方都有新的分公司,家兴表哥又让他将原来的系统扩展开来分公司。一开始家兴是打算让他们公用一套系统,就只是根据标识进行区别。后来发现不能这样使用,因为总公司和分公司以及其它的办事处可能不同,没办法共同使用,不能只是进行简单的管理?
【设计模式|组合模式--部分整体一致对待】2)解决方案
仔细分析你会发现这中情况就是部分和整体要求同同一对待,解决这种问题你会发现用组合模式可以使得用户对单个对象和组合对像的使用具有一致性。
3)使用情景
当你发现需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一使用组合结构中的所有对象时,就应该考虑用组合模式。
4)结构
Eleme:饿了么总公司接口类。定义参加组合对象的共有方法和属性。
FinancialDept:饿了么财务部类,实现eleme接口,其下没有其它的分支,是遍历最小的单位。
ResourceDept:饿了么人力资源部,实现eleme接口,其它没有其它分支,是遍历最小的单位。
Filial:饿了么的分公司,实现饿了么接口,组合类。组合树枝和叶子结点形成一个树形结构。
5)组合模式XML图
设计模式|组合模式--部分整体一致对待
文章图片

6)代码实现

//Eleme接口 public interface Eleme { public void operation(); }//财务部 public class FinancialDept implements Eleme{@Override public void operation() { // TODO Auto-generated method stub System .out.println("你好,这里是饿了么的财务部"); } }//人力资源部 public class ResourceDept implements Eleme{@Override public void operation() { // TODO Auto-generated method stub System .out.println("你好,这里是饿了么的人力资源部"); }}//分公司 import java.util.ArrayList; public class Filial implements Eleme{ private ArrayList elemeArrayList = new ArrayList(); @Override public void operation() { // TODO Auto-generated method stub for(Eleme eleme : elemeArrayList){ eleme.operation(); } }public void add(Eleme eleme){ this.elemeArrayList.add(eleme); }public void remove(Eleme eleme){ this.elemeArrayList.remove(eleme); }public Eleme getChild(int key){ return this.elemeArrayList.get(key); }public ArrayList getAllChild(){ return this.elemeArrayList; } }//客户端 public class Client {public static void main(String[] args) { // TODO Auto-generated method stub FinancialDept financialdept = new FinancialDept(); Eleme resourceDept = new ResourceDept(); Filial filial = new Filial(); Filial branchFilial = new Filial(); filial.add(financialdept); filial.add(resourceDept); filial.add(branchFilial); branchFilial.add(financialdept); show(filial); }public static void show(Filial filial){ for(Eleme f : filial.getAllChild()){ if(f instanceof ResourceDept){ System.out.println("ResourceDept部门"); f.operation(); }else if(f instanceof FinancialDept){ System.out.println("FinancialDept部门"); f.operation(); }else{ System.out.println("分公司"); show((Filial) f); } } }}

程序运行的结果
FinancialDept部门
你好,这里是饿了么的财务部
ResourceDept部门
你好,这里是饿了么的人力资源部
分公司
FinancialDept部门
你好,这里是饿了么的财务部
从程序输出的结果可以看出
组合模式可以定义包含人力资源部和财务部这些基本对象和分公司组合对象的类层次结构。
7.组合模式好处
1.基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断的递归下去,客户端代码中,任何用到基本对象的地方都可以使用组合对象了。
2.用户不用关心到底是处理一个叶节点还是处理一个组合组件,也就用不着为定义组合而写一些选择判断语句了。
8)与其它模式关系
1.与装饰模式经常一起使用时,他们通常会用一个公共的类,所以装饰必须具有Add、Remove和GetChild 操作的Component接口。
2.经常与迭代器模式一起使用,进行遍历Composite;
3.(观察者模式)Visitor将本来应该分布在Composite和L e a f类中的操作和行为局部化。

    推荐阅读