真刀实枪之组合模式

  • 从公司的人事架构谈起吧

    • 公司的组织架构

    • 从上图中可以分析出:
      1. 有分支的节点(树枝节点)
      2. 无分支的节点(叶子节点)
      3. 根节点(无父节点)
  • 有了树状结构图,再看看类图长啥样吧!
  • 这个类图是有缺陷的,等会儿继续修改,现在先看下这个不成熟类图的代码

    • IRoot

      package com.peng.zh;import java.util.ArrayList;/*** @author kungfu~peng* @data 2017年11月24日* @description*/
      public interface IRoot {// 得到总经理想要的信息public String getInfo();// 添加树枝节点public void add(IBranch banch);// 添加叶子节点public void add(ILeaf leaf);// 遍历节点public ArrayList getSubordinateInfo();
      }
      
    • Root

      package com.peng.zh;import java.util.ArrayList;/*** @author kungfu~peng* @data 2017年11月24日* @description*/
      public class Root implements IRoot {// 保存根节点下的树枝节点和叶子节点private ArrayList subordinateList = new ArrayList();// 根节点的名称private String name = "";// 根节点的职位private String position = "";// 根节点的薪水private int salary = 0;// 通过构造函数传递进来的总经理的信息Root(String name, String position, int salary) {super();this.name = name;this.position = position;this.salary = salary;}@Overridepublic String getInfo() {String info = "";info += "根节点名称:" + this.name + ",根节点职位:" + this.position + ",根节点薪水:"+ this.salary;return info;}@Overridepublic void add(IBranch branch) {this.subordinateList.add(branch);}@Overridepublic void add(ILeaf leaf) {this.subordinateList.add(leaf);}@Overridepublic ArrayList getSubordinateInfo() {return this.subordinateList;}}
      
    • IBranch

      package com.peng.zh;import java.util.ArrayList;/*** @author kungfu~peng* @data 2017年11月24日* @description*/
      public interface IBranch {// 得到信息public String getInfo();// 添加树枝节点public void add(IBranch banch);// 添加叶子节点public void add(ILeaf leaf);// 遍历节点public ArrayList getSubordinateInfo();
      }
      
    • Branch

      package com.peng.zh;import java.util.ArrayList;/*** @author kungfu~peng* @data 2017年11月24日* @description*/
      public class Branch implements IBranch {// 保存树枝节点下的树枝节点和叶子节点private ArrayList subordinateList = new ArrayList();// 树枝节点的名称private String name = "";// 树枝节点的职位private String position = "";// 树枝节点的薪水private int salary = 0;// 通过构造函数传递进来的树枝节点的信息Branch(String name, String position, int salary) {super();this.name = name;this.position = position;this.salary = salary;}@Overridepublic String getInfo() {String info = "";info += "树枝节点名称:" + this.name + ",树枝节点职位:" + this.position + ",树枝节点薪水:"+ this.salary;return info;}@Overridepublic void add(IBranch branch) {this.subordinateList.add(branch);}@Overridepublic void add(ILeaf leaf) {this.subordinateList.add(leaf);}@Overridepublic ArrayList getSubordinateInfo() {return this.subordinateList;}}
      
    • ILeaf

      package com.peng.zh;import java.util.ArrayList;/*** @author kungfu~peng* @data 2017年11月24日* @description*/
      public interface ILeaf {// 得到信息public String getInfo();}
      
    • Leaf

      package com.peng.zh;import java.util.ArrayList;/*** @author kungfu~peng* @data 2017年11月24日* @description*/
      public class Leaf implements ILeaf {// 叶子节点的名称private String name = "";// 叶子节点的职位private String position = "";// 叶子节点的薪水private int salary = 0;// 通过构造函数传递进来的叶子节点的信息Leaf(String name, String position, int salary) {super();this.name = name;this.position = position;this.salary = salary;}@Overridepublic String getInfo() {String info = "";info += "叶子节点名称:" + this.name + ",叶子节点职位:" + this.position + ",叶子节点薪水:"+ this.salary;return info;}}
      
    • Client

      package com.peng.zh;import java.util.ArrayList;/*** @author kungfu~peng* @data 2017年11月24日* @description*/
      public class Client {public static void main(String[] args) {// 先产生根节点IRoot ceo = new Root("王大麻子", "总经理", 100000);// 产生三个部门经理IBranch developDep = new Branch("刘大瘸子", "研发部门经理", 10000);IBranch salesDep = new Branch("马二拐子", "销售部门经理", 20000);IBranch financeDep = new Branch("赵三驼子", "财务部门经理", 30000);// 两个小组长IBranch firstDepGroup = new Branch("杨三也斜", "开发一组组长", 5000);IBranch secondDepGrooup = new Branch("吴大棒槌", "开发二组组长", 6000);// 研发部经理ILeaf zhengLaoLiu = new Leaf("郑老六", "研发部副总", 20000);// 员工ILeaf a = new Leaf("a", "开发人员", 2000);ILeaf b = new Leaf("b", "开发人员", 2000);ILeaf c = new Leaf("c", "开发人员", 2000);ILeaf d = new Leaf("d", "开发人员", 2000);ILeaf e = new Leaf("e", "开发人员", 2000);ILeaf f = new Leaf("f", "开发人员", 2000);ILeaf g = new Leaf("g", "开发人员", 2000);ILeaf h = new Leaf("h", "销售人员", 5000);ILeaf i = new Leaf("i", "销售人员", 4000);ILeaf j = new Leaf("j", "财务人员", 5000);ILeaf k = new Leaf("k", "ceo秘书人员", 8000);// 组装总经理ceo.add(developDep);ceo.add(salesDep);ceo.add(financeDep);ceo.add(k);// 组装研发部门developDep.add(firstDepGroup);developDep.add(secondDepGrooup);developDep.add(zhengLaoLiu);// 组装第一个开发小组firstDepGroup.add(a);firstDepGroup.add(c);firstDepGroup.add(d);// 组装第二个开发小组secondDepGrooup.add(e);secondDepGrooup.add(f);secondDepGrooup.add(g);// 组装销售部salesDep.add(h);salesDep.add(i);// 组装财务部financeDep.add(j);// 打印出来整个树形结构System.out.println(ceo.getInfo());getAllSubordinateInfo(ceo.getSubordinateInfo());}private static void getAllSubordinateInfo(ArrayList subordinateInfo) {int length = subordinateInfo.size();for (int i = 0; i < length; i++) {Object s = subordinateInfo.get(i);if (s instanceof Leaf) {ILeaf employee = (ILeaf) s;System.out.println(employee.getInfo());} else {IBranch branch = (IBranch) s;System.out.println(branch.getInfo());// 递归getAllSubordinateInfo(branch.getSubordinateInfo());}}}}
      
    • 执行结果
      根节点名称:王大麻子,根节点职位:总经理,根节点薪水:100000
      树枝节点名称:刘大瘸子,树枝节点职位:研发部门经理,树枝节点薪水:10000
      树枝节点名称:杨三也斜,树枝节点职位:开发一组组长,树枝节点薪水:5000
      叶子节点名称:a,叶子节点职位:开发人员,叶子节点薪水:2000
      叶子节点名称:c,叶子节点职位:开发人员,叶子节点薪水:2000
      叶子节点名称:d,叶子节点职位:开发人员,叶子节点薪水:2000
      树枝节点名称:吴大棒槌,树枝节点职位:开发二组组长,树枝节点薪水:6000
      叶子节点名称:e,叶子节点职位:开发人员,叶子节点薪水:2000
      叶子节点名称:f,叶子节点职位:开发人员,叶子节点薪水:2000
      叶子节点名称:g,叶子节点职位:开发人员,叶子节点薪水:2000
      叶子节点名称:郑老六,叶子节点职位:研发部副总,叶子节点薪水:20000
      树枝节点名称:马二拐子,树枝节点职位:销售部门经理,树枝节点薪水:20000
      叶子节点名称:h,叶子节点职位:销售人员,叶子节点薪水:5000
      叶子节点名称:i,叶子节点职位:销售人员,叶子节点薪水:4000
      树枝节点名称:赵三驼子,树枝节点职位:财务部门经理,树枝节点薪水:30000
      叶子节点名称:j,叶子节点职位:财务人员,叶子节点薪水:5000
      叶子节点名称:k,叶子节点职位:ceo秘书人员,叶子节点薪水:8000
      
  • 好,代码写完,把刚刚遗留的问题来找一下:
    1. getInfo每个接口都有,为什么不抽象出来?
    2. Root和Branch类有什么差别?
    3. 根节点本来就是树枝节点的一种,为什么要定义成两个接口?
    4. 若果我要增加一个任职期限,是不是所有的都要修改?
    5. 如果我要后续遍历,能做到吗?
  • 问题很多,一个一个解决

    1. 先说抽象问题,确实可以抽象出来,修改下类图

      1. 修改

      2. 仔细看这个图,能不能发现还有问题--想想接口的作用是什么?定义共性,既然是这样,那getInfo方法也可以封装啦,再继续修改
      3. 修改2
      4. 类图上增加了一个ICorp接口,它是公司所有员工的接口类
      5. 新类图的代码

        1. ICorp

          package zh2;/*** @author kungfu~peng* @data 2017年11月24日* @description*/
          public interface ICorp {// 获取信息public String getInfo();
          }
          
        2. ILeaf

          package zh2;/*** @author kungfu~peng* @data 2017年11月24日* @description*/
          public interface ILeaf extends ICorp {}
          
        3. Leaf

          package zh2;/*** @author kungfu~peng* @data 2017年11月24日* @description*/
          public class Leaf implements ILeaf {// 叶子节点的名称private String name = "";// 叶子节点的职位private String position = "";// 叶子节点的薪水private int salary = 0;// 通过构造函数传递进来的叶子节点的信息Leaf(String name, String position, int salary) {super();this.name = name;this.position = position;this.salary = salary;}@Overridepublic String getInfo() {String info = "";info += "叶子节点名称:" + this.name + ",叶子节点职位:" + this.position + ",叶子节点薪水:"+ this.salary;return info;}}
          
        4. IBranch

          package zh2;import java.util.ArrayList;/*** @author kungfu~peng* @data 2017年11月24日* @description*/
          public interface IBranch extends ICorp {// 增高增加小兵public void addSubordinate(ICorp corp);// 获得下属信息public ArrayList<ICorp> getSubordinate();// 删除下属--没用到,这里省略
          }
          
        5. Branch

          package zh2;import java.util.ArrayList;/*** @author kungfu~peng* @data 2017年11月24日* @description*/
          public class Branch implements IBranch {// 保存节点下的树枝节点和叶子节点private ArrayList<ICorp> subordinateList = new ArrayList<ICorp>();// 树枝节点的名称private String name = "";// 树枝节点的职位private String position = "";// 树枝节点的薪水private int salary = 0;// 通过构造函数传递进来的树枝节点的信息Branch(String name, String position, int salary) {super();this.name = name;this.position = position;this.salary = salary;}@Overridepublic String getInfo() {String info = "";info += "树枝节点名称:" + this.name + ",树枝节点职位:" + this.position + ",树枝节点薪水:"+ this.salary;return info;}@Overridepublic void addSubordinate(ICorp corp) {this.subordinateList.add(corp);}@Overridepublic ArrayList<ICorp> getSubordinate() {return this.subordinateList;}}
          
        6. Client

          package zh2;import java.util.ArrayList;/*** @author kungfu~peng* @data 2017年11月24日* @description*/
          public class Client {public static void main(String[] args) {// 先产生根节点Branch ceo = new Branch("王大麻子", "总经理", 100000);// 产生三个部门经理IBranch developDep = new Branch("刘大瘸子", "研发部门经理", 10000);IBranch salesDep = new Branch("马二拐子", "销售部门经理", 20000);IBranch financeDep = new Branch("赵三驼子", "财务部门经理", 30000);// 两个小组长IBranch firstDepGroup = new Branch("杨三也斜", "开发一组组长", 5000);IBranch secondDepGrooup = new Branch("吴大棒槌", "开发二组组长", 6000);// 研发部经理ILeaf zhengLaoLiu = new Leaf("郑老六", "研发部副总", 20000);// 员工ILeaf a = new Leaf("a", "开发人员", 2000);ILeaf b = new Leaf("b", "开发人员", 2000);ILeaf c = new Leaf("c", "开发人员", 2000);ILeaf d = new Leaf("d", "开发人员", 2000);ILeaf e = new Leaf("e", "开发人员", 2000);ILeaf f = new Leaf("f", "开发人员", 2000);ILeaf g = new Leaf("g", "开发人员", 2000);ILeaf h = new Leaf("h", "销售人员", 5000);ILeaf i = new Leaf("i", "销售人员", 4000);ILeaf j = new Leaf("j", "财务人员", 5000);ILeaf k = new Leaf("k", "ceo秘书人员", 8000);// 组装总经理ceo.addSubordinate(developDep);ceo.addSubordinate(salesDep);ceo.addSubordinate(financeDep);ceo.addSubordinate(k);// 组装研发部门developDep.addSubordinate(firstDepGroup);developDep.addSubordinate(secondDepGrooup);developDep.addSubordinate(zhengLaoLiu);// 组装第一个开发小组firstDepGroup.addSubordinate(a);firstDepGroup.addSubordinate(c);firstDepGroup.addSubordinate(d);// 组装第二个开发小组secondDepGrooup.addSubordinate(e);secondDepGrooup.addSubordinate(f);secondDepGrooup.addSubordinate(g);// 组装销售部salesDep.addSubordinate(h);salesDep.addSubordinate(i);// 组装财务部financeDep.addSubordinate(j);// 打印出来整个树形结构System.out.println(ceo.getInfo());getAllSubordinateInfo(ceo.getSubordinate());}private static void getAllSubordinateInfo(ArrayList subordinateInfo) {int length = subordinateInfo.size();for (int i = 0; i < length; i++) {Object s = subordinateInfo.get(i);if (s instanceof Leaf) {ILeaf employee = (ILeaf) s;System.out.println(employee.getInfo());} else {IBranch branch = (IBranch) s;System.out.println(branch.getInfo());// 递归getAllSubordinateInfo(branch.getSubordinate());}}}
          }
          
        7. 执行结果
          树枝节点名称:王大麻子,树枝节点职位:总经理,树枝节点薪水:100000
          树枝节点名称:刘大瘸子,树枝节点职位:研发部门经理,树枝节点薪水:10000
          树枝节点名称:杨三也斜,树枝节点职位:开发一组组长,树枝节点薪水:5000
          叶子节点名称:a,叶子节点职位:开发人员,叶子节点薪水:2000
          叶子节点名称:c,叶子节点职位:开发人员,叶子节点薪水:2000
          叶子节点名称:d,叶子节点职位:开发人员,叶子节点薪水:2000
          树枝节点名称:吴大棒槌,树枝节点职位:开发二组组长,树枝节点薪水:6000
          叶子节点名称:e,叶子节点职位:开发人员,叶子节点薪水:2000
          叶子节点名称:f,叶子节点职位:开发人员,叶子节点薪水:2000
          叶子节点名称:g,叶子节点职位:开发人员,叶子节点薪水:2000
          叶子节点名称:郑老六,叶子节点职位:研发部副总,叶子节点薪水:20000
          树枝节点名称:马二拐子,树枝节点职位:销售部门经理,树枝节点薪水:20000
          叶子节点名称:h,叶子节点职位:销售人员,叶子节点薪水:5000
          叶子节点名称:i,叶子节点职位:销售人员,叶子节点薪水:4000
          树枝节点名称:赵三驼子,树枝节点职位:财务部门经理,树枝节点薪水:30000
          叶子节点名称:j,叶子节点职位:财务人员,叶子节点薪水:5000
          叶子节点名称:k,叶子节点职位:ceo秘书人员,叶子节点薪水:8000
          
      6. getInfo方法都有,是不是可以继续优化,把ICorp接口变化成一个抽象类,将getInfo方法在抽象类中实现

        1. 再次修改类图

        2. 代码实现

          1. Corp

            package zh3;/*** @author kungfu~peng* @data 2017年11月25日* @description*/
            public abstract class Corp {// 树枝节点的名称private String name = "";// 树枝节点的职位private String position = "";// 树枝节点的薪水private int salary = 0;// 通过构造函数传递进来的树枝节点的信息Corp(String name, String position, int salary) {this.name = name;this.position = position;this.salary = salary;}public String getInfo() {String info = "";info += "树枝节点名称:" + this.name + ",树枝节点职位:" + this.position + ",树枝节点薪水:"+ this.salary;return info;}}
            
          2. Branch

            package zh3;import java.util.ArrayList;import zh2.ICorp;/*** @author kungfu~peng* @data 2017年11月25日* @description*/
            public class Branch extends Corp {// 保存节点下的树枝节点和叶子节点private ArrayList<Corp> subordinateList = new ArrayList<Corp>();Branch(String name, String position, int salary) {super(name, position, salary);}// 增加下属public void addSubordinate(Corp corp) {this.subordinateList.add(corp);}// 我有哪些下属public ArrayList<Corp> getSubordinate() {return this.subordinateList;}
            }
            
          3. Leaf

            package zh3;/*** @author kungfu~peng* @data 2017年11月25日* @description*/
            public class Leaf extends Corp {Leaf(String name, String position, int salary) {super(name, position, salary);}}
            
          4. Client

            package zh3;import java.util.ArrayList;/*** @author kungfu~peng* @data 2017年11月25日* @description*/
            public class Client {public static void main(String[] args) {// 先产生根节点Branch ceo = new Branch("王大麻子", "总经理", 100000);// 产生三个部门经理Branch developDep = new Branch("刘大瘸子", "研发部门经理", 10000);Branch salesDep = new Branch("马二拐子", "销售部门经理", 20000);Branch financeDep = new Branch("赵三驼子", "财务部门经理", 30000);// 两个小组长Branch firstDepGroup = new Branch("杨三也斜", "开发一组组长", 5000);Branch secondDepGrooup = new Branch("吴大棒槌", "开发二组组长", 6000);// 研发部经理Leaf zhengLaoLiu = new Leaf("郑老六", "研发部副总", 20000);// 员工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);// 组装总经理ceo.addSubordinate(developDep);ceo.addSubordinate(salesDep);ceo.addSubordinate(financeDep);ceo.addSubordinate(k);// 组装研发部门developDep.addSubordinate(firstDepGroup);developDep.addSubordinate(secondDepGrooup);developDep.addSubordinate(zhengLaoLiu);// 组装第一个开发小组firstDepGroup.addSubordinate(a);firstDepGroup.addSubordinate(c);firstDepGroup.addSubordinate(d);// 组装第二个开发小组secondDepGrooup.addSubordinate(e);secondDepGrooup.addSubordinate(f);secondDepGrooup.addSubordinate(g);// 组装销售部salesDep.addSubordinate(h);salesDep.addSubordinate(i);// 组装财务部financeDep.addSubordinate(j);// 打印出来整个树形结构System.out.println(ceo.getInfo());getAllSubordinateInfo(ceo.getSubordinate());}private static void getAllSubordinateInfo(ArrayList subordinateInfo) {int length = subordinateInfo.size();for (int i = 0; i < length; i++) {Object s = subordinateInfo.get(i);if (s instanceof Leaf) {Leaf employee = (Leaf) s;System.out.println(employee.getInfo());} else {Branch branch = (Branch) s;System.out.println(branch.getInfo());// 递归getAllSubordinateInfo(branch.getSubordinate());}}}
            }
            
          5. 执行结果
            树枝节点名称:王大麻子,树枝节点职位:总经理,树枝节点薪水:100000
            树枝节点名称:刘大瘸子,树枝节点职位:研发部门经理,树枝节点薪水:10000
            树枝节点名称:杨三也斜,树枝节点职位:开发一组组长,树枝节点薪水:5000
            树枝节点名称:a,树枝节点职位:开发人员,树枝节点薪水:2000
            树枝节点名称:c,树枝节点职位:开发人员,树枝节点薪水:2000
            树枝节点名称:d,树枝节点职位:开发人员,树枝节点薪水:2000
            树枝节点名称:吴大棒槌,树枝节点职位:开发二组组长,树枝节点薪水:6000
            树枝节点名称:e,树枝节点职位:开发人员,树枝节点薪水:2000
            树枝节点名称:f,树枝节点职位:开发人员,树枝节点薪水:2000
            树枝节点名称:g,树枝节点职位:开发人员,树枝节点薪水:2000
            树枝节点名称:郑老六,树枝节点职位:研发部副总,树枝节点薪水:20000
            树枝节点名称:马二拐子,树枝节点职位:销售部门经理,树枝节点薪水:20000
            树枝节点名称:h,树枝节点职位:销售人员,树枝节点薪水:5000
            树枝节点名称:i,树枝节点职位:销售人员,树枝节点薪水:4000
            树枝节点名称:赵三驼子,树枝节点职位:财务部门经理,树枝节点薪水:30000
            树枝节点名称:j,树枝节点职位:财务人员,树枝节点薪水:5000
            树枝节点名称:k,树枝节点职位:ceo秘书人员,树枝节点薪水:8000
            

组合模式的定义

  • Composite Pattern
  • 也叫合成模式或整体-部分模式,主要是描述部分与整体的关系
  • Compose objects into tree structures to represent part-whole hirearchies.Composite lets clients treat individual objects and compositions of objects uniformly.(将对象组合成树形结构,以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性)

通用类图

  • 几个角色
    1. Component抽象构建角色:可以定义属性和方法
    2. Leaf叶子构件:遍历的最小单位
    3. Composite树枝构件:中间节点或根节点
  • 通用代码这里不再赘述

组合模式的应用

  • 组合模式的优点

    1. 高层模块调用简单
    2. 节点自由增加
  • 组合模式的缺点
    1. 场景类直接使用了树叶节点和树枝节点,这在面向接口编程上是很不恰当的,与依赖原则冲突
  • 使用场景
    1. 维护和展示“部分-整体”关系的场景--树形菜单、文件和文件夹管理
    2. 从一个整体中能够独立出部分模块或功能的场景

组合模式的注意事项

  • 只要是树形结构就考虑组合模式--体现“部分-整体”关系的时候

组合模式的扩展

  • 安全模式的组合模式【之前写的就是】
  • 透明的组合模式
    • 类图

      • 透明模式就是将组合使用的方法放到抽象类中,不管是叶子还是树枝都有这个方法,通过判断getChild的返回值确定是叶子节点还是树枝节点,如果处理不当,运行期间会出问题
      • 不是很建议这种方式
      • 代码--注意叶子节点的add方法的重写--抛出“不支持请求异常”即可--throw new UnsupportedOperationException();
  • 组合模式的遍历
    1. 上到下【上面的已经实现】
    2. 下到上【增加parent】
      1. 类图

        1. ​​​​​​​
      2. 代码(看了这么多,自己动手试一试)

最佳实践

  • 页面结构【top,center(left,right),bottom】
  • JavaScript
  • xml
  • 血缘关系

声明

  • 摘自秦小波《设计模式之禅》第2版;
  • 仅供学习,严禁商业用途;
  • 代码手写,没有经编译器编译,有个别错误,自行根据上下文改正;

设计模式之禅【组合模式】相关推荐

  1. 组合模式_设计模式结构性:组合模式(CompositePattern)

    组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结构型模式, ...

  2. JAVA设计模式初探之组合模式

    先看看组合模式的定义吧:"将对象组合成树形结构以表示'部分-整体'的层次结构.组合模式使得用户对单个对象和组合对象的使用具有一致性." 就拿剪发办卡的事情来分析一下吧. 首先,一张 ...

  3. 从王者荣耀看设计模式(五.组合模式)

    从王者荣耀看设计模式(组合模式) 一.简介 在王者荣耀这款游戏中,我们可以在商店中购买英雄.英雄由法师.射手.打野等职业组合而成,其中各个职业由中国元素的英雄和外国元素的英雄组成,玩家可根据需要挑选并 ...

  4. 《设计模式》12.组合模式(结构型)

    又称"整体-部分"模式,组合多个对象形成树形结构以表示具有"整体-部分"关系的层次结构,使用户对单个对象和组合对象具有访问一致性. 角色 抽象构件(Compon ...

  5. AVA设计模式初探之组合模式

    先看看组合模式的定义吧:"将对象组合成树形结构以表示'部分-整体'的层次结构.组合模式使得用户对单个对象和组合对象的使用具有一致性." 就拿剪发办卡的事情来分析一下吧. 首先,一张 ...

  6. JAVA设计模式十七--Composite(组合模式)

    组合模式 组合模式(Composite Pattern)有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念   ,客户程序可以向处理简单元素一样来处理复杂元素,从而使 ...

  7. 再战设计模式(九)之组合模式

    组合模式 工作流程分析 组合模式为处理树形结构提供了完美的解决方案,描述了如何将容器和叶子进行递归组合,使得用户在使用时可以一致性的对待容器和叶子 当容器对象的指定方法被调用时,将遍历整个树形结构,寻 ...

  8. 设计模式(17)之组合模式

    一.前言 在现实生活中,存在很多"部分-整体"的关系,例如,大学中的部门与学院.总公司中的部门与分公司.学习用品中的书与书包.生活用品中的衣服与衣柜.以及厨房中的锅碗瓢盆等.在软件 ...

  9. 设计模式:(组合模式)

    1.定义 组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结 ...

  10. 设计模式笔记(9)---组合模式(结构型)

    Gof定义 将对象组合成树形结构以表示"部分--整体"的层次结构.Composite使得用户对单个对象和组合对象使用具有一致性. 在面向对象系统中,我们经常会遇到一类具有" ...

最新文章

  1. JDK9,像Unix脚本一样执行Java代码
  2. PriorityBlockingQueue用法
  3. VTK:几何对象之Pyramid
  4. autopep8规范你的python代码
  5. 神州泰岳2050万元收买并增资奇点国际
  6. 让事件飞——Linux eventfd 原理
  7. b超可以看出什么_B超可以查出什么
  8. 教程和攻略之悪戯極~いたずらリアル~(3D电车监禁)+初回特典
  9. 转:Mysql explain
  10. 苹果开发者账号那些事儿(三)
  11. cocos2d Labels and Fonts 标签和字体
  12. 2019年税务师进行继续教育?
  13. GCode_interpreter解读
  14. VTK点云数据如何导入MeshLab
  15. 徐家骏是华为数据中心的头,技术超级牛人,一级部门总监,华为副总裁,年收入过千万。
  16. Sql 语句小课堂7:在sqlserver对多行数据实施随机数
  17. 隐私计算--37--演讲实录:深入浅出谈联邦学习
  18. 计算机网络应用智能家居,计算机智能化网络应用研究
  19. python光棍节快乐_光棍节快乐的祝福语12条
  20. Linux网络连接NAT模式

热门文章

  1. C++ 基础入门 之 结构体/结构体定义和使用/结构体数组/结构体指针/ 结构体嵌套结构体/结构体做函数参数/结构体中 const 使用场景/结构体案例
  2. cocos3.X拖动精灵移动
  3. 解决gitlab-runner一直处于等待中
  4. flash 磨损均衡处理
  5. 2022元宇宙共享大会|倪健中:我们正在开启元宇宙新时代
  6. Python实现两两交换链表中的节点
  7. Android中百度地图基础实现,定位
  8. 2016基于百度地图定位
  9. T细胞培养、分离方法大比拼
  10. html中图像标记的属性,HTML中的图象标签属性