- 概述
- UML类图
- 代码栗子
- 总结
-
概述
概念 组合模式是指将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。
-
作用:让客户端不再区分操作的是组合对象还是叶子对象,而是以一个统一的方式来操作。
UML类图
-
代码栗子
栗子 主管与下属
-
code
public interface ICorp { /** * 获取员工信息 * @return */ String getInfo() ; } //叶子节点 public interface ILeaf extends ICorp{ /** * 获取员工信息 * @return */ @Override String getInfo() ; } //树枝 public interface IBranch extends ICorp { /** * 增加员工(树叶节点)或者是经理(树枝节点) * @param corp */ void addSubordinate(ICorp corp); /** * 获得下属的信息 * @return */ ArrayList<ICorp> getSubordinate(); }
public class Branch implements IBranch{ /** * 名称 */ private String name; /** * 职位 */ private String position; /** * 薪水 */ private int salary; ArrayList<ICorp> subordinateList = new ArrayList<>(); public Branch(String name,String position,int salary){ this.name = name; this.position = position; this.salary = salary; } /** * 增加一个下属,可能是小头目,也可能是个小兵 * @param corp */ @Override public void addSubordinate(ICorp corp) { this.subordinateList.add(corp); } /** * 我有哪些下属 * @return */ @Override public ArrayList<ICorp> getSubordinate() { return this.subordinateList; } /** * 领导也是人,他也有信息 * @return */ @Override public String getInfo() { String info = ""; info = "姓名:" + this.name; info = info + "\t职位:"+ this.position; info = info + "\t薪水:" + this.salary; return info; } }
public class Leaf implements ILeaf{ /** * 名称 */ private String name; /** * 职位 */ private String position; /** * 薪水 */ private int salary ; public Leaf(String name,String position,int salary){ this.name = name; this.position = position; this.salary = salary; } /** * 获得小兵的信息 * @return */ @Override public String getInfo() { String info = ""; info = "姓名:" + this.name; info = info + "\t职位:"+ this.position; info = info + "\t薪水:" + this.salary; return info; } }
-
测试
public class Client { /** * ceo */ private static Branch ceo; /** * 开发经理 */ private static Branch developDep; /** * 财务经理 */ private static Branch financeDep; static { //初始化组织结构 ceo = new Branch("马总", "总经理", 100000); developDep = new Branch("张三", "研发部门经理", 10000); financeDep = new Branch("里斯", "财务部经理", 20000); Leaf a = new Leaf("a", "开发人员", 2000); Leaf b = new Leaf("b", "开发人员", 2000); Leaf c = new Leaf("c", "开发人员", 2000); Leaf d = new Leaf("d", "财务人员", 4000); Leaf e = new Leaf("e", "财务人员", 4000); Leaf f = new Leaf("f", "财务人员", 4000); ceo.addSubordinate(developDep); ceo.addSubordinate(financeDep); developDep.addSubordinate(a); developDep.addSubordinate(b); developDep.addSubordinate(c); financeDep.addSubordinate(d); financeDep.addSubordinate(e); financeDep.addSubordinate(f); } public static void main(String[] args) { // //首先把CEO的信息打印出来 System.out.println(ceo.getInfo()); //然后是所有员工信息 System.out.println(getTreeInfo(ceo)); } /** * 遍历整棵树,只要给我根节点,我就能遍历出所有的节点 * @param root * @return */ public static String getTreeInfo(Branch root) { ArrayList<ICorp> subordinateList = root.getSubordinate(); String info = ""; for (ICorp s : subordinateList) { /** * 是员工就直接获得信息 */ if (s instanceof Leaf) { info = info + s.getInfo() + "\n"; } else { //是个小头目 info = info + s.getInfo() + "\n" + getTreeInfo((Branch) s); } } return info; } }
-
-
总结
-
场景
当遇到想表示树形结构时(如菜单栏 等),优先考虑组合模式
-
缺点
安全性和透明性是互相矛盾的,这是由于叶子节点和非叶子节点行为的不一致以及需要提供一个一致的行为接口所造成的,是不可调和的矛盾
-
实际中,组合模式的大多数使用场景可以通过表设计进行规范解决
ps: 这样就可以呈现出一个树形结构
-
参考资料
书籍:《设计模式之禅》