1. 程式人生 > >面向對象可復用設計幾大原則

面向對象可復用設計幾大原則

編程 原因 合成 接口編程 裏氏替換 做成 不能 任務 方法

1、開-閉 原則:指的是一個軟件實體應該對擴展開放,對修改關閉。用面向對象的語言來講就是:不允許修改的是系統的抽象層,允許擴展的是系統的具體實現層。

2、裏氏代換原則:一個軟件實體如果使用的是一個基類的話,那麽一定適用於其子類,而且它根本不能察覺出基類對象和子類對象的區別。

3、依賴倒轉原則:要求客戶端依賴於抽象耦合。

  另一種表述是:要針對接口編程,不要針對實現編程(Program to an interface , not an implementation)。

  如果設計師希望遵守“開-閉”原則,那麽依賴倒轉原則便是達到要求的途徑。

  依賴倒轉原則是OO設計的核心原則,設計模式的研究和應用是以依賴倒轉原則為指導原則的。

4、接口隔離原則:使用多個專門的接口比使用單一的總接口要好,一個類對另外一個類的依賴性應當是建立在最小的接口上的。

  通俗點說就是如果一個功能需要依賴多個功能,那個把每個功能都做成單獨的接口開放出來,不要把多個接口合並在一個接口裏面提供。

5、合成/聚合復用原則:要盡量使用合成/聚合,盡量不要使用繼承。

  5.1、繼承復用

    繼承復用通過擴展一個已有對象的實現來得到新的功能,基類明顯地捕獲共同的屬性和方法,而子類通過增加新的屬性和方法來擴展超類的實現。繼承是類型的復用。

    繼承復用的優點:

    •   新的實現較為容易,因為超類的大部分功能可通過繼承關系自動進入子類;
    •   修改或擴展繼承而來的實現較為容易。

    繼承復用的缺點:

    •   繼承復用破壞封裝,因為繼承將超類的實現細節暴露給子類。“白箱”復用;
    •   如果超類的實現發生改變,那麽子類的實現也不得不發生改變。
    •   從超類繼承而來的實現是靜態的,不可能再運行時間內發生改變,因此沒有足夠的靈活性。
  5.2、合成/聚合復用

    由於合成/聚合可以將已有的對象納入到新對象中,使之成為新對象的一部分,因此新的對象可以調用已有對象的功能,

    其優點在於:

    •   新對象存取成分對象的唯一方法是通過成分對象的接口;
    •   成分對象的內部細節對新對象不可見。 “黑箱”復用;
    •   該復用支持封裝。
    •   該復用所需的依賴較少。
    •   每一個新的類可將焦點集中在一個任務上。
    •   該復用可在運行時間內動態進行,新對象可動態引用於成分對象類型相同的對象。

     缺點:

    •   通過這種復用建造的系統會有較多的對象需要管理。
    •   為了能將多個不同的對象作為組合塊(composition block)來使用,必須仔細地對接口進行定義。
     要正確的選擇合成/復用和繼承,必須透徹地理解裏氏替換原則和Coad法則。

    Coad法則由Peter Coad提出,總結了一些什麽時候使用繼承作為復用工具的條件。 Coad法則:

    只有當以下Coad條件全部被滿足時,才應當使用繼承關系:

    1.   子類是超類的一個特殊種類,而不是超類的一個角色。區分“Has-A”和“Is-A”。只有“Is-A”關系才符合繼承關系,“Has-A”關系應當用聚合來描述。
    2.   永遠不會出現需要將子類換成另外一個類的子類的情況。如果不能肯定將來是否會變成另外一個子類的話,就不要使用繼承。
    3.   子類具有擴展超類的責任,而不是具有置換掉(override)或註銷掉(Nullify)超類的責任。如果一個子類需要大量的置換掉超類的行為,那麽這個類就不應該是這個超類的子類。
    4.   只有在分類學角度上有意義時,才可以使用繼承。不要從工具類繼承。
    錯誤地使用繼承而不是合成/聚合的一個常見原因是錯誤的把“Has-A”當成了“Is-A”。
    “Is-A”代表一個類是另外一個類的一種;
    “Has-A”代表一個類是另外一個類的一個角色,而不是另外一個類的特殊種類。 6、迪米特法則:一個對象應當對其它對象有盡可能少的了解。盡量降低類與類之間的耦合。通俗的來講,就是一個類對自己依賴的類知道的越少越好。   也就是說,對於被依賴的類來說,無論邏輯多麽復雜,都盡量地的將邏輯封裝在類的內部,對外除了提供的public方法,不對外泄漏任何信息。迪米特法則還有一個更簡單的定義:只與直接的朋友通信。

面向對象可復用設計幾大原則