設計模式之組合模式---Composite Pattern

hfreeman2008發表於2016-08-05

模式的定義

組合模式(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類圖

這裡寫圖片描述

角色介紹

  • 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類圖

這裡寫圖片描述

具體實現程式碼

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

相關文章