设计模式之组合模式

版权声明:本文为 冬夏 原创文章,可以随意转载,但请注明出处。

组合模式(Composite)允许你将对象组合成树形结构来表现“整体/部分”层次结构。

说到组合模式,Android 开发者们第一反应都会想到 View/ViewGroup。没错,View/ViewGroup 正是通过组合模式使用户能够以树状的形式访问它们。那么组合模式究竟是如何实现的呢?首先看一下组合模式的 UML 图。

假设我们现在有这么一个需求:需要按部门和等级建立公司的人员结构图,由于公司的组织结构和人员变动随时都有可能发生,所以,所以不能采用一个固定的数据结构。这种情况下使用组合模式是一个很好的选择。

我们尝试从组合模式的UML中找找编程的灵感。我们可以发现组合模式存在着一下几个特点:

  1. 叶子类和非叶子类都继承自同一个组合类
  2. 叶子类和非叶子类有针对性地继承组合父类的某些方法。

接着尝试用组合模式解决我们的需求。假设将所有员工分为两类,领导和员工,领导有雇佣和开除员工的权限,而员工有执行具体任务的业务能力。首先新建公共父类,拥有员工和领导的所有方法。

public class Component {
    protected String name;
    List<Component> subordinate;

    public Component(String name){
        this.name = name;
        subordinate = new ArrayList<>();
    }


    public void add(Component c)//增加成员
    {
        throw new UnsupportedOperationException("该员工不支持此操作");
    }
    public void remove(Component c){ //删除成员
        throw new UnsupportedOperationException("该员工不支持此操作");
    }
    public Component getChild(int i){ //获取成员
        throw new UnsupportedOperationException("该员工不支持此操作");
    }
    public void operation(){  //业务方法
        throw new UnsupportedOperationException("该员工不支持此操作");
    }

    public List<Component> getSubordinate() {
        return subordinate;
    }

    @Override
    public String toString() {
        return name;
    }

    public void printAll(){
        System.out.println(this);
        for (Component employee : this.getSubordinate()) {
            employee.printAll();
        }
    }
}

接着建立领导类和职员类

public class Employer extends Component {

    public Employer(String name){
        super(name);
    }

    public void add(Component c)//增加成员
    {
        subordinate.add(c);
    }
    public void remove(Component c){ //删除成员
        subordinate.remove(c);
    }
    public Component getChild(int i){ //获取成员
        return subordinate.get(i);
    }
}

public class Employee extends Component {

    public Employee(String name){
        super(name);
    }

    @Override
    public void operation() {
        System.out.println("员工执行业务操作");
    }
}

最后我们就可以简单地实现访问所有的员工了

public class Main {
    public static void main(String[] agrs){
        Employer CEO = new Employer("John");

        Employer headSales = new Employer("Robert");

        Employer headMarketing = new Employer("Michel");

        Employee clerk1 = new Employee("Laura");
        Employee clerk2 = new Employee("Bob");

        Employee salesExecutive1 = new Employee("Richard");
        Employee salesExecutive2 = new Employee("Rob");

        CEO.add(headSales);
        CEO.add(headMarketing);

        headSales.add(salesExecutive1);
        headSales.add(salesExecutive2);

        headMarketing.add(clerk1);
        headMarketing.add(clerk2);

        //打印该组织的所有员工
        CEO.printAll();
    }
}

最后说一下组合模式的优缺点:

优点:

  1. 高层模块调用简单,由于不管是树枝还是叶子,对于高层来说都是 Component,所以对调用者来说没有任何区别。
  2. 节点自由增减,从代码中可以看出,如果想要在某个节点下新增节点,只要找到父节点就好了,非常容易扩展,符合开闭原则,对以后的维护非常有利。

缺点:

  1. 设计复杂,客户端需要花更多时间理清类之间的层次关系。(这个是几乎所有设计模式所面临的问题)。
  2. 指向不明,由于对于调用者来说,并不清楚当前节点是树枝还是树叶。
冬夏 wechat
欢迎您扫一扫上面的二维码,关注我的个人公众号:Android从入门到精通
坚持原创技术分享,您的支持将鼓励我继续创作