package com.cheng.zenofdesignpatterns.patterns.composite; import android.view.View; import com.cheng.zenofdesignpatterns.ZoDPChapterBaseActivity; import com.cheng.zenofdesignpatterns.patterns.composite.common.Component; import com.cheng.zenofdesignpatterns.patterns.composite.common.Composite; import com.cheng.zenofdesignpatterns.patterns.composite.common.Leaf; import com.cheng.zenofdesignpatterns.patterns.composite.transmode.TransModeComponent; import com.cheng.zenofdesignpatterns.patterns.composite.transmode.TransModeComposite; import com.cheng.zenofdesignpatterns.patterns.composite.transmode.TransModeLeaf; import com.cheng.zenofdesignpatterns.patterns.composite.treestat.Branch; import com.cheng.zenofdesignpatterns.patterns.composite.treestat.Corp; import com.cheng.zenofdesignpatterns.patterns.composite.treestat.TreestatLeaf; import java.util.ArrayList; public class ZoDPCompositeActivity extends ZoDPChapterBaseActivity { @Override protected void initData() { mTitleTV.setText("组合模式"); String content = "定义:\n" + "Compose objects into tree structures to represent part-whole hierarchies." + "TransModeComposite lets clients treat individual objects and compositions " + "of objects uniformly.\n" + "将对象组合成树形结构以表示‘部分-整体’的层次结构,使得用户对单个对象和组合对象的" + "使用具有一致性。\n\n" + "组合模式的优点\n" + "- 高层模块调用简单\n" + "一棵树结构中的所有节点都是Component,局部和整体对地拥着来说没有任何区别,也就是" + "说,高层模块不必关系自己处理的是单个对象还是整个组合结构,简化了高层模块的代码。\n" + "- 节点自由增加\n" + "使用了组合模式后,可以看看,如果想增加一个树枝节点、树叶节点都很容易,只要找到它" + "的父节点就成,非常容易扩展,符合开闭原则,对以后的维护非常有利。\n" + "组合模式的缺点\n" + "在树叶和树枝使用时,直接使用了实现类。这在面向接口编程上是很不恰当的,与依赖倒置" + "原则冲突。\n\n" + "使用场景\n" + "- 维护和展示部分-整体关系的场景,如树形菜单、文件和文件夹管理\n" + "- 从一个整体中能够独立出部分模块或功能的场景\n\n" + "注意事项\n" + "只要是树形结构,就要考虑使用组合模式,这个一定要记住,只要是要体现局部和整体的关" + "系还可能比较深,考虑一下组合模式吧。\n\n" + "最佳实践\n" + "树状结构、XML、成员结构。"; mContentTV.setText(content); } @Override public void onClick(View v) { // 1. 模拟公司人员结构 // 首先是组装一个组织结构出来 Branch ceo = compositeCorpTree(); // 首先把CEO的信息打印出来: System.out.println(ceo.getInfo()); // 然后是所有员工信息 System.out.println(getTreeInfo(ceo)); // 2. 通用组合模式演示 // 2.1 安全组合模式 Composite root = new Composite(); root.doSomething(); Composite branch = new Composite(); Leaf leaf = new Leaf(); root.add(branch); branch.add(leaf); display(root); // 2.2 透明组合模式 // 创建一个根节点 TransModeComposite tmroot = new TransModeComposite(); tmroot.doSomething(); // 创建一个树枝构件 TransModeComposite tmbranch = new TransModeComposite(); // 创建一个叶子节点 TransModeLeaf tmleaf = new TransModeLeaf(); // 建立整体 tmroot.add(tmbranch); tmbranch.add(tmleaf); display(tmroot); } // 把整个树组装出来 private Branch compositeCorpTree(){ // 首先产生总经理CEO Branch root = new Branch("王大麻子","总经理",100000); // 把三个部门经理产生出来 Branch developDep = new Branch("刘大瘸子","研发部门经理",10000); Branch salesDep = new Branch("马二拐子","销售部门经理",20000); Branch financeDep = new Branch("赵三驼子","财务部经理",30000); // 再把三个小组长产生出来 Branch firstDevGroup = new Branch("杨三乜斜","开发一组组长",5000); Branch secondDevGroup = new Branch("吴大棒槌","开发二组组长",6000); // 把所有的小兵都产生出来 TreestatLeaf a = new TreestatLeaf("a","开发人员",2000); TreestatLeaf b = new TreestatLeaf("b","开发人员",2000); TreestatLeaf c = new TreestatLeaf("c","开发人员",2000); TreestatLeaf d = new TreestatLeaf("d","开发人员",2000); TreestatLeaf e = new TreestatLeaf("e","开发人员",2000); TreestatLeaf f = new TreestatLeaf("f","开发人员",2000); TreestatLeaf g = new TreestatLeaf("g","开发人员",2000); TreestatLeaf h = new TreestatLeaf("h","销售人员",5000); TreestatLeaf i = new TreestatLeaf("i","销售人员",4000); TreestatLeaf j = new TreestatLeaf("j","财务人员",5000); TreestatLeaf k = new TreestatLeaf("k","CEO秘书",8000); TreestatLeaf zhengLaoLiu = new TreestatLeaf("郑老六","研发部副经理",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; } // 遍历整棵树,只要给我根节点,我就能遍历出所有的节点 private String getTreeInfo(Branch root){ ArrayList<Corp> subordinateList = root.getSubordinate(); String info = ""; for (Corp s : subordinateList) { if (s instanceof TreestatLeaf) { //是员工就直接获得信息 info = info+ s.getInfo()+"\n"; } else { // 是个小头目 info = info +s.getInfo() +"\n"+ getTreeInfo((Branch)s); } } return info; } private void display(Composite root) { // 通过递归遍历树 for (Component c : root.getChildren()) { if (c instanceof Leaf) { // 叶子节点 c.doSomething(); } else { display((Composite) c); // 普通模式下需要强转 } } } private void display(TransModeComponent root) { // 通过递归遍历树 for (TransModeComponent c : root.getChildren()) { if (c instanceof TransModeLeaf) { // 叶子节点 c.doSomething(); } else { display(c); // 透明模式下不需要强转 } } } }