模式的定义

组合模式(Composite Pattern)定义如下:

Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly。

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

组合模式有时叫做部分—整体模式,主要是描述部分与整体的关系。

模式的使用场景

  1. 部分-整体关系的场景,如树形菜单,文件和文件夹管理
  2. 从一个整体中能够独立出部分模块或功能的场景

UML类图

设计模式之组合模式---Composite  Pattern_设计模式

角色介绍

  • Component 抽象构件角色

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

  • Leaf 叶子组件

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

  • Composite 树枝构件

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

模式的简单实现

Component:

public abstract class Component {

    //个体和整体都具有的共享
    public void doSomething(){
        //业务逻辑
        System.out.print("Component-----doSomething()");
    }
}

Leaf :

public class Leaf extends Component {

    //可以覆写父类方法
    /* (non-Javadoc)
     * @see Component#doSomething()
     */
    @Override
    public void doSomething() {
        // TODO Auto-generated method stub
        super.doSomething();
        System.out.print("Leaf-------doSomething()");
    }


    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return super.toString();
    }
}

Composite :

public class Composite extends Component{

    private ArrayList<Component> components = new ArrayList<Component>();

    public void add(Component component){
        components.add(component);
    }

    public void remove(Component component){
        components.remove(component);
    }

    public ArrayList<Component> getChildren(){
        return components;
    }

}

Client:

public class Client {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //create a root
        Composite root =  new Composite();
        root.doSomething();

        //create a branch
        Composite branch = new Composite();
        root.add(branch);

        //create a leaf
        Leaf leaf1 = new Leaf();
        root.add(leaf1);

        //create a leaf
        Leaf leaf2 = new Leaf();
        root.add(leaf2);

        Display(root);

    }


    private static void Display(Composite root) {
        // TODO Auto-generated method stub
        for(Component c:root.getChildren()){
            if(c instanceof Leaf){
                System.out.println();
                System.out.print("leaf----"+c.toString());

            }else {
                System.out.println();
                System.out.print("Composite----"+c.toString());
                Display((Composite)c);

            }
        }
    }

}

优点

  • 高层模块调用简单

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

  • 节点自由增加

使用组合模式后,增加一个树枝节点,树叶节点都很容易,只要找到父节点就可以非常容易扩展,符合开闭原则,对以后的维护非常有利。

缺点

组合模式有一个明显的缺点,看我们的场景类中的定义,提到树叶与树枝使用时的定义。直接使用了实现类。这在面向接口编程上是不恰当的,与依赖倒置原则总被。

注意事项

只要是树形结构,就要考虑使用组合模式,这个一定要记住。只要是要体现局部和整体的关系的时候,而且这种关系还可能比较深,考虑一下组合模式。

Android源码中的模式实现

UML类图

设计模式之组合模式---Composite  Pattern_Pattern_02

具体实现代码

View.java

public class View ....{
 //此处省略无关代码...
}

ViewGroup.java

public abstract class ViewGroup extends View ...{

     private View[] mChildren;

     //增加子节点
    public void addView(View child, int index) { 

    }
    //增加子节点
    public void addView(View child) {
        addView(child, -1);
    }
    //删除子节点
    public void removeView(View view) {

    }
     //查找子节点
    public View getChildAt(int index) {
        if (index < 0 || index >= mChildrenCount) {
            return null;
        }
        return mChildren[index];
    }
}

参考资料

(1).设计模式之禅—第21章 组合模式
(2)composite Pattern 组合模式
https://github.com/simple-android-framework/android_design_patterns_analysis/tree/master/composite/tiny-times