美文网首页
组合模式

组合模式

作者: 缓慢移动的蜗牛 | 来源:发表于2019-11-26 20:44 被阅读0次

组合模式的定义

定义:将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有抑制性。

通用类图如下:

组合模式通用类图.png

角色说明

  • Component抽象构件角色

    定义参加组合对象的公共方法和属性。可以定义一些默认的行为或者属性

  • Leaf叶子构件

    叶子对象,其下再也没有其他的分支,也就是遍历的最小单位。

  • Composite树枝构件

    树枝对象,它的作用是组合树枝节点和叶子节点形成一个树形结构。

通用源码

抽象构件

public abstract class Component {
     //个体和整体都具有的共享
     public void doSomething(){
             //编写业务逻辑
     }
}

树枝构件

public class Composite extends Component {
     //构件容器
     private ArrayList<Component> componentArrayList = new ArrayList<Component>();
     //增加一个叶子构件或树枝构件
     public void add(Component component){
             this.componentArrayList.add(component);
     }
     //删除一个叶子构件或树枝构件
     public void remove(Component component){
             this.componentArrayList.remove(component);
     }
     //获得分支下的所有叶子构件和树枝构件
     public ArrayList&lt;Component&gt; getChildren(){
             return this.componentArrayList;
     }
}

树叶构件

public class Leaf extends Component {
     /*
      * 可以覆写父类方法
      * public void doSomething(){
      *
      * }
      */
}

场景类

public class Client {
     public static void main(String[] args) {
            //创建一个根节点
             Composite root = new Composite();
             root.doSomething();
             //创建一个树枝构件
             Composite branch = new Composite();
             //创建一个叶子节点
             Leaf leaf = new Leaf();
             //建立整体
             root.add(branch);
             branch.add(leaf);
     }
     //通过递归遍历树
     public static void display(Composite root){
             for(Component c:root.getChildren()){
                  if(c instanceof Leaf){ //叶子节点
                          c.doSomething();
                  }else{ //树枝节点
                          display((Composite)c);
                  }
             }
     }
}

组合模式的应用

优点

  • 高层模块调用简单

    一个树形结构中所有的节点都是Component,局部和整体对调用者来说没有任何区别,也就是,高层模块不必关系自己处理的是单个对象还是整个组合结构,简化了高层模块的代码。

  • 节点自由增加

    使用了组合莫时候,如果想增加一个树枝节点、树叶节点都很容易。

缺点

组合模式有个非常明显的缺点,直接使用了实现类,这在面向接口编程上是很不恰当的,与依赖倒置原则冲突。

使用场景

  • 维护和展示部分——整体关系的场景,如树形菜单、文件和文件夹管理。
  • 从一个整体中能够独立出部分模块或功能的场景。

组合模式的两种实现

组合模式有两种不同的实现:透明模式和安全模式

透明模式:把用来组合使用的方法放到抽象类中,比如add()remove()以及getChildren()方法,不管叶子对象还是树枝都有相同的结构,通过判断getChildren()的返回值来确认是叶子节点还是树枝节点,如果处理不当,这个会在运行期出现问题,不建议

安全模式:把树枝节点和树叶节点彻底分开,树枝节点单独拥有用来组合的方法,这种方法比较安全。

安全组合模式的示例

用组合模式来表示一个公司的组织架构

类图如下:

组合模式--公司组织架构类图.png

抽象构件

public abstract class Corp {
     //公司每个人都有名称
     private String name = "";
     //公司每个人都职位
     private String position = "";
     //公司每个人都有薪水
     private int salary =0;
     //记录当前节点的父节点
     private Corp parent = null;
     public Corp(String name,String position,int salary){
             this.name = name;
             this.position = position;
             this.salary = salary;
     }
     //获得员工信息
     public String getInfo(){
             String info = "";
             info = "姓名:" + this.name;
             info = info + "\t职位:"+ this.position;
             info = info + "\t薪水:" + this.salary;
             return info;
     }
     //设置父节点
     protected void setParent(Corp parent){
             this.parent = parent;
     }
     //得到父节点
     public Corp getParent(){
             return this.parent;
     }
}

树枝构件

public class Branch extends Corp {
     //领导下边有哪些下级领导和小兵
     ArrayList<Corp> subordinateList = new ArrayList<Corp>();
     //构造函数是必需的
     public Branch(String name,String position,int salary){
             super(name,position,salary);
     }
     //增加一个下属,可能是小头目,也可能是个小兵
     public void addSubordinate(Corp corp) {
             corp.setParent(this); //设置父节点
             this.subordinateList.add(corp);
     }
     //我有哪些下属
     public ArrayList<Corp> getSubordinate() {
             return this.subordinateList;
     }
}

树叶节点

public class Leaf extends Corp {
     //就写一个构造函数,这个是必需的
     public Leaf(String name,String position,int salary){
             super(name,position,salary);
     }
}

场景类

public class Client {
    public static void main(String[] args) {
        compositeCorpTree();
    }

    public static Branch compositeCorpTree(){
        Branch root = new Branch("王大麻子", "总经理", 100000);

        //产生三个部门经理,也是分枝节点
        Branch developDep = new Branch("刘", "研发部门经理", 2000);
        Branch salesDep = new Branch("王", "销售部经理", 3000);
        Branch financeDep = new Branch("高", "财务部经理", 4000);
        Branch firstDevGroup = new Branch("阳伞", "开发一组组长", 5);
        Branch secondDevGroup = new Branch("san", "开发二组组长", 5);

        //小兵
        Leaf a = new Leaf("a", "开发人员", 10);
        Leaf b = new Leaf("b", "开发人员", 10);
        Leaf c = new Leaf("c", "开发人员", 10);
        Leaf d = new Leaf("d", "开发人员", 10);
        Leaf e = new Leaf("e", "开发人员", 10);
        Leaf f = new Leaf("f", "开发人员", 10);
        Leaf g = new Leaf("g", "开发人员", 10);
        Leaf h = new Leaf("h", "销售人员", 10);
        Leaf i = new Leaf("i", "销售人员", 10);
        Leaf j = new Leaf("g", "财务人员", 10);
        Leaf k = new Leaf("k", "CEO秘书", 10);
        Leaf zhengLaoLiu = new Leaf("正老刘", "研发部副总", 1023);


        //组织关系
        root.addSubordinate(developDep);
        root.addSubordinate(salesDep);
        root.addSubordinate(financeDep);
        root.addSubordinate(k);

        developDep.addSubordinate(firstDevGroup);
        developDep.addSubordinate(secondDevGroup);
        developDep.addSubordinate(zhengLaoLiu);
        firstDevGroup.addSubordinate(a);
        firstDevGroup.addSubordinate(b);
        firstDevGroup.addSubordinate(c);
        secondDevGroup.addSubordinate(d);
        secondDevGroup.addSubordinate(e);
        secondDevGroup.addSubordinate(g);

        salesDep.addSubordinate(h);
        salesDep.addSubordinate(i);

        financeDep.addSubordinate(j);

        System.out.println(root.getInfo());

        //打印整个树形
        getAllSubordinateInfo(root.getSubordinate());

        return root;
    }

    private static void getAllSubordinateInfo(List<Corp> subordinateList){
        int length = subordinateList.size();
        for (int i = 0; i < length; i++) {
            Corp o = subordinateList.get(i);
            System.out.println(o.getInfo());
            if (o instanceof Branch) {
                Branch branch = (Branch)o;
                //递归调用其子节点
                getAllSubordinateInfo(branch.getSubordinate());
            }
        }
    }
}

透明组合模式的示例

类图如下:

透明模式的组合模式.png

抽象组件

public abstract class Component {
    /**
     * 个体和整体都具有的共享
     */
    public abstract void doSomething();

    /**
     * 增加一个叶子构件或树枝构件
     * @param component
     */
    public abstract void add(Component component);

    /**
     * 删除一个叶子构件或树枝构件
     * @param component
     */
    public abstract void remove(Component component);

    /**
     * 获得分枝下的所有叶子构件或树枝构件
     * @return
     */
    public abstract List<Component> getChildren();
}

树枝

public class Composite extends Component{
    List<Component> subordinateList = new ArrayList<>();
    @Override
    public void doSomething() {

    }

    @Override
    public void add(Component component) {
        this.subordinateList.add(component);
    }

    @Override
    public void remove(Component component) {
        this.subordinateList.remove(component);
    }

    @Override
    public List<Component> getChildren() {
        return this.subordinateList;
    }
}

树叶

public class Leaf extends Component{
    @Override
    public void doSomething() {

    }

    @Deprecated
    @Override
    public void add(Component component) throws UnsupportedOperationException{
        throw new UnsupportedOperationException();
    }

    @Deprecated
    @Override
    public void remove(Component component) throws UnsupportedOperationException{
        throw new UnsupportedOperationException();
    }

    @Deprecated
    @Override
    public List<Component> getChildren() throws UnsupportedOperationException{
        throw new UnsupportedOperationException();
    }
}

相关文章

  • 设计模式:组合模式 职责链模式

    组合模式 职责链模式 组合模式 组合模式将对象组合成树形结构,以表示“部分-整体”的层次结构。 在组合模式的树形结...

  • 第4章 结构型模式-组合模式

    一、组合模式简介 二、组合模式的优缺点 三、组合模式的使用场景 、组合模式的实例

  • 组合模式(统一叶子与组合对象)

    目录 从生活场景出发,映射组合模式 组合模式的理论概念 组合模式的实现 组合模式在源码中的应用 组合 “优于” 继...

  • 组合模式

    1. 组合模式 1.1 组合模式的定义 组合模式(Composite): 又称部分-整体模式, 将对象组合成树形结...

  • 组合模式

    设计模式系列7--组合模式 《Objective-c 编程之道 iOS 设计模式解析》 - 组合模式 常见组合模式...

  • 设计模式 | 组合模式及典型应用

    本文的主要内容: 介绍组合模式 示例 组合模式总结 源码分析组合模式的典型应用java.awt中的组合模式Java...

  • 组合模式

    一、组合模式介绍 二、组合模式代码实例

  • 组合模式

    设计模式之组合模式 什么是组合模式? 组合模式允许你将对象组合成树形结构来表现”部分-整体“的层次结构,使得客户以...

  • 15、组合模式(Composite Pattern)

    1. 组合模式 1.1 简介   Composite模式,即组合模式,又叫部分整体模式。Composite模式将对...

  • 组合模式原型解析

    组合模式定义: 组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象...

网友评论

      本文标题:组合模式

      本文链接:https://www.haomeiwen.com/subject/nkgywctx.html