淺學設計模式之組合模式及在Android中的應用

來源:互聯網
上載者:User
定義

        組合模式允許你將對象組合成樹形結構來表現出“整體/部分”階層。組合能以一致的方式處理個別對象以及對象組合。



結構圖

            



          使用者使用Compoment類介面與組合結構中的對象進行互動。如果接受者是一個分葉節點,則直接處理請求。如果接受者是Composite,它通常將請求發送給他的子組件,在轉寄請求之前或者之後可能執行一些輔助操作。


程式碼範例

component:

public abstract class Component {    public int getChildNum(){    throw new UnsupportedOperationException();    };    public Component getChild(int i){    throw new UnsupportedOperationException();    }    public String getType(){    throw new UnsupportedOperationException();    };    public String getName(){    throw new UnsupportedOperationException();    };    public void add(Component c){    throw new UnsupportedOperationException();    };    public void remove(Component c){    throw new UnsupportedOperationException();        };  //        public abstract void print();}

leaf:

public class Leaf extends Component {private String strType = "leat";private String strName = "Leat";public Leaf(String strName){this.strName = strName;}    public String getType(){    return strType;    };    public String getName(){    return strName;    };@Overridepublic void print() {// TODO Auto-generated method stubSystem.out.println("i am "+getName());}}

composite:

public class Branches extends Component {private ArrayList list;private String strType = "composite";private String strName = "Branches";public Branches(String strName){list = new ArrayList();this.strName = strName;}public int getSize(){return list.size();};    public int getChildNum(){    return list.size();    };    public Component getChild(int i){    if(i<=list.size()){    return (Component) list.get(i);    } else {    return null;    }        }    public String getType(){    return strType;    };    public String getName(){    return strName;    };    public void add(Component c){    list.add(c);    };    public void remove(Component c){    list.remove(c);    };@Overridepublic void print() {// TODO Auto-generated method stubIterator iterator = list.iterator();while(iterator.hasNext()){((Component)iterator.next()).print();System.out.println("belong to "+getName());}System.out.println("i am "+getName());}}

public class Tree extends Component {private ArrayList list;private String strType = "composite";private String strName = "Tree";public Tree(String strName){list = new ArrayList();this.strName = strName;}public int getSize(){return list.size();};    public int getChildNum(){    return list.size();    };    public Component getChild(int i){    if(i<=list.size()){    return (Component) list.get(i);    } else {    return null;    }        }    public String getType(){    return strType;    };    public String getName(){    return strName;    };    public void add(Component c){    list.add(c);    };    public void remove(Component c){    list.remove(c);    };@Overridepublic void print() {// TODO Auto-generated method stubIterator iterator = list.iterator();while(iterator.hasNext()){((Component)iterator.next()).print();}System.out.println("i am "+getName());}}

client:

public static void main(String[] args) {// TODO Auto-generated method stubComponent tree = new Tree("楊樹");Component branches1 = new Branches("branches1");Component branches2 = new Branches("branches2");Component branches3 = new Branches("branches3");Component branches4 = new Branches("branches4");Component leaf1 = new Leaf("leaf1");Component leaf2 = new Leaf("leaf2");Component leaf3 = new Leaf("leaf3");Component leaf4 = new Leaf("leaf4");Component leaf5 = new Leaf("leaf5");Component leaf6 = new Leaf("leaf6");Component leaf7 = new Leaf("leaf7");Component leaf8 = new Leaf("leaf8");tree.add(branches1);tree.add(branches2);tree.add(branches3);tree.add(branches4);branches1.add(leaf1);branches1.add(leaf2);branches2.add(leaf3);branches2.add(leaf4);branches3.add(leaf5);branches3.add(leaf6);branches4.add(leaf7);branches4.add(leaf8);tree.print();}

測試結果:

i am leaf1belong to branches1i am leaf2belong to branches1i am branches1i am leaf3belong to branches2i am leaf4belong to branches2i am branches2i am leaf5belong to branches3i am leaf6belong to branches3i am branches3i am leaf7belong to branches4i am leaf8belong to branches4i am branches4i am 楊樹

        該代碼用樹(此樹非資料結構中的樹)來示範組合模式。代碼較簡單,但能清晰的體現組合模式的優點。

深入分析

      

        將客戶代碼與複雜的對象容器結構解耦是組合模式的核心思想,解耦之後,客戶代碼將與純粹的抽象介面——而非對象容器的複內部實現結構——發生依賴關係,從而更能應對變化。

        組合模式中必須提供對子物件的管理方法,不然無法完成對子物件的添加刪除等等操作,也就失去了靈活性和擴充性。但是管理方法是在Component中就聲明還是在Composite中聲明呢?一種方式是在Component裡面聲明所有的用來管理子類對象的方法,以達到Component介面的最大化。目的就是為了使客戶看來在介面層次上樹葉和分支沒有區別——透明性。但樹葉是不存在子類的,因此聲明的一些方法對於樹葉來說是不適用的。這樣也就帶來了一些安全性問題。另一種方式就是只在Composite裡面聲明所有的用來管理子類對象的方法。這樣就避免了上一種方式的安全性問題,但是由於葉子和分支有不同的介面,所以又失去了透明性。《設計模式》一書認為:在這一模式中,相對於安全性,我們比較強調透明性。對於第一種方式中葉子節點內不需要的方法可以使用空處理或者異常報告的方式來解決。

組合模式在具體實現中,可以讓父物件中的子物件反向追溯;如果父物件有頻繁的遍曆需求,可使用緩衝技巧來改善效率。

要點
  • Composite模式採用樹形結構來實現普遍存在的對象容器,從而將“一對多”的關係轉化為“一對一”的關係,使得客戶代碼可以一致的處理對象和對象容器,無需關心處理的是單個對象,還是組合的對象容器。

  • 將“客戶代碼與複雜的對象容器結構”解耦是Composite模式的核心思想,解耦之後,客戶代碼將與純粹的對象介面——而非對象容器的複雜內部實現結構——發生依賴關係,從而更能“應對變化”。

  • Composite模式中,是將“Add和Remove的和對象容器相關的方法”定義在“表示抽象對象的Component類”中,還是將其定義在“表示對象容器的Composite類”中,是一個關乎“透明性”和“安全性”的兩難問題,需要仔細權衡結構,這又是必須付出的代價。

  • Composite模式在具體實現中,可以讓父物件中的字對象反向追溯:如果父物件有頻繁的遍曆需求,可使用緩衝技巧來改善效率

適用性:

     以下情況使用Composite模式:

  1. 想表示對象的部分-整體階層。
  2. 希望使用者忽略組合對象與單個對象的不同,使用者將統一地使用組合結構中的所有對象。

 

優點:
  1. 組合模式可以很容易的增加新的構件。
  2. 使用組合模式可以使用戶端變的很容易設計,因為用戶端可以對組合和分葉節點一視同仁。
缺點:
  1.  使用組合模式後,控制樹枝構件的類型不太容易。
  2.  用繼承的方法來增加新的行為很困難。

在android中的應用

         在android中,View類是典型的組合模式。

  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.