<大話設計模式>本教程說明及著作權聲明
l 該文檔參考和使用了網路上的免費開放的圖片和內容,並以免費開放的方式發布,希望為移動互連網和智能手機時代貢獻綿薄之力!可以隨意轉載,但不得使用該文檔謀利。
l 如果對該文檔有任何疑問或者建議,請進入官方部落格
http://www.cnblogs.com/guoshiandroid/留言或者直接與國士工作室聯絡(後附連絡方式),我們會謹慎參考您的建議並根據需要對本文檔進行修改,以造福更多開發人員!
l 《大話設計模式》的最新及完整內容會在國士工作室官方部落格定期更新,請訪問國士工作室部落格
http://www.cnblogs.com/guoshiandroid/擷取更多更新內容。
國士工作室是一支專註於Android平台企業級應用開發的技術團隊,致力於做中國最棒的Android應用程式開發機構,提供最棒的Android企業級應用開發培訓服務。
企業培訓和開發合作官方連絡方式:
電話:18610086859
Email:hiheartfirst@gmail.com
QQ:1740415547
QQ群:148325348
國士工作室 有你更美好!
查
看其他部分:本教程整體說明及章節索引
本文PDF下載連結
合成彙總複用原則 劉邦VS韓信
應用情境舉例:
VS
一次,劉邦閑著沒事,又想起了故人韓信,於是開啟QQ想和韓信聊天,正巧韓信也在,開始寒暄了幾句,就在不自覺中進入嚴肅的問題,劉邦問:“韓兄覺得如果是我帶兵,最多能夠帶多少呢?”,韓信立即回複說:“十萬”,劉邦心想本王竟然只能帶十萬,那你韓信又能夠帶多少呢,於是暫時按捺了心中的鬱悶,很客氣的問道:“那請問韓兄最多能夠帶多少呢”,韓信又立即回複道:“我啊,那自然是越多越好啦”,劉邦看到此言頓時大怒,而且語氣還極其的傲慢,還“啊,啦”的,劉邦心想:“雖然你韓信帶兵打仗有道,天下皆知,但是這樣對本王說話也太過分了吧”,劉邦正要發飆,隨即停了一下,深諳世道的劉邦問了一句:“將軍神勇蓋世,帶兵百萬,卻為何會在我領導下呢?”,劉邦想:“好你個韓信,叫了你幾聲韓兄你就不知道自己是誰了,如果回答不上來,或是回答不好,看我如何收拾你!”,等了大約三秒鐘,QQ閃了一下,只見上面赫然寫道:“陛下雖不善統兵,卻善禦將”。劉邦大悅!
定義:
合成彙總複用原則(Composite Aggregate Reuse Principle,簡稱為CARP)經常又被人們稱為合成複用原則(Composite Reuse Principle,簡稱為CRP).合成彙總複用原則是指在一個新的對象中使用原來已經存在的一些對象,是這些原來已經存在的對象稱為新對象的一部分,新的對象通過向這些原來已經具有的對象委派相應的動作或者命令達到複用已有功能的目的。
合成複用原則跟簡潔的表述是:要盡量使用合成和彙總,盡量不要使用繼承。
彙總(Aggregation)是關聯關係的一種,用來表示一種整體和部分的擁有關係。整體持有對部分的引用,可以調用部分的能夠被訪問的方法和屬性等,當然這種訪問往往是對介面和抽象類別的訪問。作為部分可以可以同時被多個新的對象引用,同時為多個新的對象提供服務。
合成(Composition)也是關聯關係的一種,但合成是一種比彙總強得多的一種關聯關係。在合成關係裡面,部分和整體的生命週期是一樣的。作為整體的新對象完全擁有對作為部分的支配權,包括負責和支配部分的建立和銷毀等,即要負責作為部分的記憶體的分配和記憶體釋放等。從這裡也可以看出來,一個合成關係中的成員對象是不能喝另外的一個合成關係共用的。
為何“要盡量使用合成和彙總,盡量不要使用繼承”呢?這是因為:第一,繼承複用破壞封裝,它把超類的實現細節直接暴露給了子類,這違背了資訊隱藏的原則;第二:如果超類發生了改變,那麼子類也要發生相應的改變,這就直接導致了類與類之間的高耦合,不利於類的擴充、複用、維護等,也帶來了系統僵硬和脆弱的設計。而是用合成和彙總的時候新對象和已有對象的互動往往是通過介面或者抽象類別進行的,就可以很好的避免上面的不足,而且這也可以讓每一個新的類專註於實現自己的任務,符合單一職責原則。
彙總關係的如下所示:
彙總關係的如下所示:
故事分析:
“韓信帶兵,多多益善”,韓信之所以有很大的影響力,一方面歸功他建立了很大的功勳;另外一方面是因為他手握重兵。建立很大的功勳甚至是功高蓋主,這就直接導致韓信在軍隊中深得人心,畢竟,作為士兵,很少有不願意追隨一個在戰場上無往不勝的領袖的;手握重兵,有合成彙總的原則來說就是對自己統領計程車兵將士保持有引用,就是彙總。韓信手中彙總有一大批能征善戰的人,隨時聽從韓信的調遣,這是不能不讓劉邦戒備的。而現在,又說了一個自己帶兵多多益善的話,這怎能不讓劉邦感覺生氣呢?
而“普天之下,莫非王土;四海之內,莫非王臣”,韓信擁有士兵,劉邦卻擁有天下,何況韓信也並非擁有全部士兵。“君叫臣死,臣不得不死”,劉邦擁有對天下蒼生的生殺大權。韓信很清楚,“陛下雖不善統兵,卻善禦將”。劉邦是擁有一種比韓信更強的“擁有”關係,可以主宰生死,同時也可以主宰韓信的生死。這就相當於合成關係。更重要的是韓信也是合成關係的一個成員,是劉邦的將領。所以說劉邦比韓信更加強悍!
如所示:
Java代碼實現:
建立大臣的介面:
package com.diermeng.designPattern.CARP; /* * 大臣的介面 */ public interface Minister { /* * 大臣能夠執行的動作 */ public void duty(); } |
士兵的介面
package com.diermeng.designPattern.CARP; /* * 士兵的介面 */ public interface Soldier { /* * 士兵能夠執行的動作 */ public void duty(); } |
韓信對大臣介面的實現
package com.diermeng.designPattern.CARP.impl; import com.diermeng.designPattern.CARP.Minister; import com.diermeng.designPattern.CARP.Soldier; /* * 韓信對大臣介面的實現 */ public class Hanxin implements Minister { //對士兵的彙總關係 Soldier[] soldiers; /* * 無參構造方法 */ public Hanxin() {} /* * 有士兵參數的構造方法 */ public Hanxin(Soldier[] soldiers) { super(); this.soldiers = soldiers; } /* * 擷取士兵的集合 */ public Soldier[] getSoldiers() { return soldiers; } /* * 設定士兵的集合 */ public void setSoldiers(Soldier[] soldiers) { this.soldiers = soldiers; } /* * 韓信的職能 * @see com.diermeng.designPattern.CARP.Minister#duty() */ public void duty() { System.out.println("我是劉邦的大臣,永遠忠實於劉邦"); } } |
士兵A對士兵介面的實現
package com.diermeng.designPattern.CARP.impl; import com.diermeng.designPattern.CARP.Soldier; /* * 士兵A */ public class SoldierA implements Soldier { /* * 士兵A的職責 * @see com.diermeng.designPattern.CARP.Soldier#duty() */ public void duty() { System.out.println("我是韓信計程車兵A"); } } |
士兵B對士兵介面的實現
package com.diermeng.designPattern.CARP.impl; import com.diermeng.designPattern.CARP.Soldier; /* * 士兵B */ public class SoldierB implements Soldier { /* * 士兵B的職責 * @see com.diermeng.designPattern.CARP.Soldier#duty() */ public void duty() { System.out.println("我是韓信計程車兵B"); } } |
劉邦類
package com.diermeng.designPattern.CARP.impl; import com.diermeng.designPattern.CARP.Minister; /* * 劉邦類 */ public class Liubang { //擁有大臣 Minister[] minister; /* * 無參構造方法 */ public Liubang() {} /* * 把大臣的數組作為參數傳入構造方法 */ public Liubang(Minister[] minister) { super(); this.minister = minister; } /* * 擷取大臣的集合 */ public Minister[] getMinister() { return minister; } /* * 設定大臣的集合 */ public void setMinister(Minister[] minister) { this.minister = minister; } /* * 劉邦的職能 */ public void duty() { System.out.println("我是皇帝,普天之下,莫非王土;四海之內,莫非王臣"); } } |
建立一個測試類別,代碼如下:
package com.diermeng.designPattern.CARP.client; import com.diermeng.designPattern.CARP.Minister; import com.diermeng.designPattern.CARP.Soldier; import com.diermeng.designPattern.CARP.impl.Hanxin; import com.diermeng.designPattern.CARP.impl.Liubang; import com.diermeng.designPattern.CARP.impl.SoldierA; import com.diermeng.designPattern.CARP.impl.SoldierB; /* * 測試類別的用戶端 */ public class CARPClient { public static void main(String[] args) { //聲明並執行個體化士兵A Soldier soldierA = new SoldierA(); //聲明並執行個體化士兵B Soldier soldierB = new SoldierB(); //構造士兵數組 Soldier[] soldiers = {soldierA,soldierB}; //聲明並執行個體化韓信,同時傳入士兵數組 Minister hanxin = new Hanxin(soldiers); //構造大臣數組 Minister[] minister = {hanxin}; //聲明並執行個體化劉邦,同時傳入大臣數組 Liubang liubang = new Liubang(minister); liubang.duty(); //迴圈輸出大臣 for(Minister aminister:liubang.getMinister()){ aminister.duty(); } } } |
程式運行結果如下:
我是皇帝,普天之下,莫非王土;四海之內,莫非王臣 我是劉邦的大臣,永遠忠實於劉邦 |
已有應用簡介:
對於物件導向的軟體系統而言,如何提高軟體的可維護性和可複用性始終是一個核心問題。合成彙總複用原則的合理而充分的使用時非常有利於構建可維護、可複用、可擴充和靈活性好的軟體系統。合成彙總複用原則作為一種構造優質系統的手段幾乎可以應用到任何環境中去。對於已有的應用這裡就不在贅述啦。
溫馨提示:
合成彙總複用原則雖然幾乎可以應用到任何環境中去,但是這個原則也有自己的缺點。因為此原則鼓勵使用已有的類和對象來構建新的類的對象,這就導致了系統中會有很多的類和對象需要管理和維護,從而增加系統的複雜性。
同時,也不是說在任何環境下使用合成彙總複用原則就是最好的,如果兩個類之間在符合分類學的前提下有明顯的“IS-A”的關係,而且基類能夠抽象出子類的共有的屬性和方法,而此時子類有能通過增加父類的屬性和方法來擴充基類,那麼此時使用繼承將是一種更好的選擇。
注意:該文檔參考和使用了網路上的免費開放的圖片和內容,並以免費開放的方式發布,希望為移動互連網和智能手機時代貢獻綿薄之力!可以隨意轉載,但不得使用該文檔謀利。