天天看點

設計模式原則(5)合成聚合原則

(Composite/Aggregate ReusePrinciple ,CARP)要盡量使用對象組合,而不是繼承關系達到軟體複用的目的

定義:經常又叫做合成複用原則(Composite ReusePrinciple或CRP),盡量使用對象組合,而不是繼承來達到複用的目的。

就是在一個新的對象裡面使用一些已有的對象,使之成為新對象的一部分;新對象通過向這些對象的委派達到複用已有功能的目的。簡而言之,要盡量使用合成/聚合,盡量不要使用繼承。

原則分析:

1)在面向對象設計中,可以通過兩種基本方法在不同的環境中複用已有的設計和實作,即通過 組合 / 聚合關系或通過 繼承。 繼承複用:實作簡單,易于擴充。破壞系統的封裝性;從基類繼承而來的實作是靜态的,不可能在運作時發生改變,沒有足夠的靈活性;隻能在有限的環境中使用。( “白箱”複用) 組合/聚合複用:耦合度相對較低,選擇性地調用成員對象的操作;可以在運作時動态進行。( “黑箱”複用) 2)組合/聚合可以 使系統更加靈活,類與類之間的 耦合度降低,一個類的變化對其他類造成的影響相對較少,是以一般 首選使用組合 / 聚合來實作複用;其次才考慮繼承,在使用繼承時,需要嚴格遵循裡氏代換原則,有效使用繼承會有助于對問題的了解,降低複雜度,而濫用繼承反而會增加系統建構和維護的難度以及系統的複雜度,是以需要 慎重使用繼承複用。 3)此原則和裡氏代換原則氏相輔相成的,兩者都是具體實作"開-閉"原則的規範。違反這一原則,就無法實作"開-閉"原則,首先我們要明白合成和聚合的概念: 什麼是合成 ? 合成(組合):表示一個整體與部分的關系, 指一個依托整體而存在的關系( 整體與部分 不可以分開 ),例如:一個人對他的房子和家具,其中他的房子和家具是不能被共享的,因為那些東西都是他自己的。并且人沒了,這個也關系就沒了。這個例子就好像,烏雞百鳳丸這個産品,它是有烏雞和上等藥材合成而來的一樣。 也比如網絡遊戲中的武器裝備合成一樣,多種東西合并為一種超強的東西一樣。 雖然組合表示的是一個整體與部分的關系,但是組合關系中部分和整體具有統一的生存期。一旦整體對象不存在,部分對象也将不存在,部分對象與整體對象之間具有同生共死的關系。 在組合關系中,成員類是整體類的一部分,而且整體類可以控制成員類的生命周期,即成員類的存在依賴于整體類。 在UML中,組合關系用帶實心菱形的直線表示。

設計模式原則(5)合成聚合原則
public class Head  
{  
    private Mouth mouth;  
    public Head() {  
        mouth = new Mouth();  
    }  
}  
public class Mouth  
{  
}  
           

  什麼是聚合 ? 聚合: 聚合是比合成關系更弱的一種擁有關系,也表示整體與部分的關系(整體與部分可以分開),例如,一個奔馳S360汽車,對奔馳S360引擎,奔馳S360輪胎的關系..這些關系就是帶有聚合性質的。因為奔馳S360引擎和奔馳S360輪胎他們隻能被奔馳S360汽車所用,離開了奔馳S360汽車,它們就失去了存在的意義。在我們的設計中,這樣的關系不應該頻繁出現.這樣會增大設計的耦合度。 在面向對象中的聚合:通常在定義一個整體類後,再去分析這個整體類的組成結構,進而找出一些成員類,該整體類和成員類之間就形成了聚合關系。在聚合關系中, 成員類是整體類的一部分,即成員對象是整體對象的一部分,但是成員對象可以脫離整體對象獨立存在。 在UML中,聚合關系用帶空心菱形的直線表示。  比如汽車和汽車引擎:

設計模式原則(5)合成聚合原則
public class Car  
{  
    private Engine engine;  
    public Car(Engine engine) {  
        this.engine = engine;  
    }  
    public void setEngine(Engine engine) {  
        this.engine = engine;  
    }  
}  
public class Engine  
{  
}  
           

明白了合成和聚合關系,再來了解合成/聚合原則應該就清楚了。要避免在系統設計中出現,一個類的繼承層次超過3次。如果這樣的話,可以考慮重構你的代碼,或者重新設計結構. 當然最好的辦法就是考慮使用合成/聚合原則。

轉載自:http://blog.csdn.net/hguisu/article/details/7571617

繼續閱讀