组合模式

Posted tanoak

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了组合模式相关的知识,希望对你有一定的参考价值。

  • 概述
  • UML类图
  • 代码栗子
  • 总结
  1. 概述

    • 概念 组合模式是指将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。

    • 作用:让客户端不再区分操作的是组合对象还是叶子对象,而是以一个统一的方式来操作。

      技术图片

  2. UML类图

    技术图片

  3. 代码栗子

    • 栗子 公司与部门、文件与文件夹、

    • 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 + "	职位:"+ this.position;
              info = info + "	薪水:" + 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 + "	职位:"+ this.position;
              info = info + "	薪水:" + 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() + "
        ";
                    } else { //是个小头目
                        info = info + s.getInfo() + "
        " + getTreeInfo((Branch) s);
                    }
                }
                return info;
            }
        }
  4. 总结

    • 场景

      当遇到想表示树形结构时(如菜单栏 等),优先考虑组合模式

    • 缺点

      安全性和透明性是互相矛盾的,这是由于叶子节点和非叶子节点行为的不一致以及需要提供一个一致的行为接口所造成的,是不可调和的矛盾

    • 实际中,组合模式的大多数使用场景可以通过表设计进行规范解决

      ps: 这样就可以呈现出一个树形结构

      技术图片

    参考资料

    书籍:《设计模式之禅》

以上是关于组合模式的主要内容,如果未能解决你的问题,请参考以下文章

如何组合绑定片段而不将它们包装在 XML 文字中

48个值得掌握的JavaScript代码片段(上)

Tailwind.css 体验总结

Tailwind.css 体验总结

用于从 cloudkit 检索单列的代码模式/片段

精心收集的 48 个 JavaScript 代码片段,仅需 30 秒就可理解!(转载)