1、组合模式定义
组合模式是将对象组合成树形结构以表示“部分-整体”的层次结构。它使得用户对单个对象的使用和组合对象的使用具有一致性。组合模式又叫做树形模式。其在项目开发中涉及树的结构都会想到组合模式。
2、组合模式的类图
3、组合模式分类
组合模式分为透明方式和安全方式。
透明模式是在Component类中声明对象的所有方法。叶子类和组合类都继承该类,使得叶子类和组合类都具有component中的所有方法。这样,叶子类和组合类对外界没有区别,它们具有完全一致的行为接口。但叶子类实现的诸如add、remove的方法显然是无意义的。
安全模式是componet中只声明叶子类和组合类的公共方法。在组合类中声明自己的管理子类的方法。由于叶子类和子类不具备统一的接口,在操作调用过程中要不断判断,给用户带来诸多的不便。
4、组合模式的应用
当需求要求体现部分与整体的层次结构,而又使用户可忽略组合对象和单个对象的不同,统一运用组合结构中的对象时,采用组合模式。
5、组合模式的优缺点
组合模式可以使用户统一地对待单个对象和组合对象,使用单个对象的地方就可使用组合对象。但客户端调用时因为直接调用了单个对象和组合对象,因此耦合性比较紧,需要单个对象和组合对象的结构相对比较稳定,不易发生变化时才使用该模式。
6、组合模式的典型应用 组件树结构的信息
package com.cvicse.component; /** * @author Administrator * */ public abstract class Component { //名字 private String name; //职位 private String position; //工资 private int salary; //构造函数 public Component(String name,String position,int salary){ this.name=name; this.position=position; this.salary=salary; } //获取员工信息 public String getInfor(){ String info = ""; info = "姓名:" + this.name; info = info + "\t职位:"+ this.position; info = info + "\t薪水:" + this.salary; return info; } }
package com.cvicse.component; public class Leaf extends Component { public Leaf(String name, String position, int salary) { super(name, position, salary); } }
package com.cvicse.component; import java.util.ArrayList; public class Composite extends Component { //领导下边有那些下级领导和小兵 private ArrayList<Component> subordinateList = new ArrayList<Component>(); public Composite(String name, String position, int salary) { super(name, position, salary); } //增加一个下属,可能是小头目,也可能是个小兵 public void addSubordinate(Component component) { this.subordinateList.add(component); } //我有哪些下属 public ArrayList<Component> getSubordinate() { return this.subordinateList; } }
package com.cvicse.component; import java.util.ArrayList; public class Client { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub //首先是组装一个组织结构出来 Composite ceo = compositeCorpTree(); //首先把CEO的信息打印出来: System.out.println(ceo.getInfor()); //然后是所有员工信息 System.out.println(getTreeInfo(ceo)); } // 把整个树组装出来 public static Composite compositeCorpTree() { // 首先产生总经理CEO Composite root = new Composite("王雷", "总经理", 100000); // 把三个部门经理产生出来 Composite developDep = new Composite("刘鑫", "研发部门经理", 10000); Composite salesDep = new Composite("马明", "销售部门经理", 20000); Composite financeDep = new Composite("赵岩", "财务部经理", 30000); // 再把三个小组长产生出来 Composite firstDevGroup = new Composite("杨辉", "开发一组组长", 5000); Composite secondDevGroup = new Composite("吴起", "开发二组组长", 6000); // 把所有的小兵都产生出来 Leaf a = new Leaf("a", "开发人员", 2000); Leaf b = new Leaf("b", "开发人员", 2000); Leaf c = new Leaf("c", "开发人员", 2000); Leaf d = new Leaf("d", "开发人员", 2000); Leaf e = new Leaf("e", "开发人员", 2000); Leaf f = new Leaf("f", "开发人员", 2000); Leaf g = new Leaf("g", "开发人员", 2000); Leaf h = new Leaf("h", "销售人员", 5000); Leaf i = new Leaf("i", "销售人员", 4000); Leaf j = new Leaf("j", "财务人员", 5000); Leaf k = new Leaf("k", "CEO秘书", 8000); Leaf zhengLaoLiu = new Leaf("郑剑", "研发部副经理", 20000); // 开始组装 // CEO下有三个部门经理和一个秘书 root.addSubordinate(k); root.addSubordinate(developDep); root.addSubordinate(salesDep); root.addSubordinate(financeDep); // 研发部经理 developDep.addSubordinate(zhengLaoLiu); developDep.addSubordinate(firstDevGroup); developDep.addSubordinate(secondDevGroup); // 看看开发两个开发小组下有什么 firstDevGroup.addSubordinate(a); firstDevGroup.addSubordinate(b); firstDevGroup.addSubordinate(c); secondDevGroup.addSubordinate(d); secondDevGroup.addSubordinate(e); secondDevGroup.addSubordinate(f); // 再看销售部下的人员情况 salesDep.addSubordinate(h); salesDep.addSubordinate(i); // 最后一个财务 financeDep.addSubordinate(j); return root; } // 遍历整棵树,只要给我根节点,我就能遍历出所有的节点 public static String getTreeInfo(Composite root) { ArrayList<Component> subordinateList = root.getSubordinate(); String info = ""; for (Component s : subordinateList) { if (s instanceof Leaf) { // 是员工就直接获得信息 info = info + s.getInfor() + "\n"; } else { // 是个小头目 info = info + s.getInfor() + "\n" + getTreeInfo((Composite) s); } } return info; } }
运行结果;
姓名:王雷 职位:总经理 薪水:100000
姓名:k 职位:CEO秘书 薪水:8000
姓名:刘鑫 职位:研发部门经理 薪水:10000
姓名:郑剑 职位:研发部副经理 薪水:20000
姓名:杨辉 职位:开发一组组长 薪水:5000
姓名:a 职位:开发人员 薪水:2000
姓名:b 职位:开发人员 薪水:2000
姓名:c 职位:开发人员 薪水:2000
姓名:吴起 职位:开发二组组长 薪水:6000
姓名:d 职位:开发人员 薪水:2000
姓名:e 职位:开发人员 薪水:2000
姓名:f 职位:开发人员 薪水:2000
姓名:马明 职位:销售部门经理 薪水:20000
姓名:h 职位:销售人员 薪水:5000
姓名:i 职位:销售人员 薪水:4000
姓名:赵岩 职位:财务部经理 薪水:30000
姓名:j 职位:财务人员 薪水:5000