面向對象的設計原則

 1。軟件的可維護性與可複用性

軟件的維護就是軟件的再生。系統的設計目標: 可擴展性,靈活性,可插入性。
可擴展性: 新的功能很容易集成到現有的系統中去,而不影響到系統的其他模塊。
靈活性: 允許代碼修改平穩的發生。當修改一處時不至於影響到另一處,這樣可以縮小維護的代價。
可插入性: 容易用一個類替換已經存在的類。只要接口一致,更改實現類不影響類的使用者。
軟件的複用可以提高軟件的生產率,並且恰當的複用可以提高軟件的可維護性。
在以前,複用主要是代碼,函數,結構的複用,而現在複用主要針對類,接口,組件等等。但是複用並不一定會保證軟件的可維護性。不能因爲代碼的重複等原因就複用,需要根據具體的情況來分析。要想通過複用來加強系統的可維護性,必須保證複用是支持可維護性的複用。

下面的一些設計原則可以用來指導實踐。

2。開-閉 原則(OCP)

開閉原則是面向對象可複用的基石。它主要指:一個軟件實體對擴展開放,對修改關閉。在設計一個模塊的時候,應當是這個模塊在不被修改前提下被擴展。滿足這個原則的系統在一個較高層次上實現了複用,也是易於維護的。

那如何才能滿足開閉原則呢?抽象化是關鍵。要區分開抽象層和實現層。在一個軟件系統中,抽象層應該是相對穩定的,而實現層是可以改變擴展的。

開閉原則也是對可變性的封裝原則。找到系統的可變因素,並將其封裝起來。把一種可變性封裝爲一個對象,那麼這種可變性的不同表象就是這個類的具體子類。

3。里氏代換原則(LSP)

里氏代換原則是繼承複用的基石:在任何父類出現的地方都可以用它的子類來替代。例如正方形和長方形。正方形是一種特殊的長方形。但是正方形卻不能作爲長方形的子類。因對長方形的操作並不一定能套用在正方形上。如:resize().如果正方形作爲長方形的子類的話,那麼就會出現很多問題。不符合里氏代換原則,正方形就不能作爲長方形的子類,應該把正方形和長方形都作爲四邊形的子類。在實際,設計類的階層繫結構時,這是一條很重要的原則。不應該作爲子類不能硬套。

4。依賴倒轉原則(DIP)

依賴倒轉原則是:要依賴於抽象,不要依賴於具體的實現。

爲什麼叫依賴倒轉原則呢? 在傳統的過程性系統中,高層的模塊依賴於低層次的模塊,抽象層次依賴於具體層次。這樣導致了底層的任何改變都會影響到上層。這樣的軟件系統沒有可維護性而言。
抽象層次應該不依賴於具體的實現細節,這樣才能保證系統的可複用性和可維護性,這也就是所謂的倒轉。

在實際中如何應用這一原則呢?
要針對藉口編程,而不針對實現編程。那麼當實現變化時,不會影響到其他的地方。 在java中應當使用接口和抽象類來進行變量的類型聲明,

參數的類型聲明,方法的返回值類型,等等。比如: List list = new Linkedlist();

以抽象的方式進行耦合是依賴倒轉原則的關鍵。

依照依賴倒轉原則,在系統中會出現大量的類,如抽象類和接口,因爲它假定所有的具類都是有可能變化的。但實際上這也不總是正確的。有些具體類是非常穩定的,就不需要爲他發明一種新的類型。

5。 接口隔離原則(ISP)

使用多個專門的藉口總是比使用單一的總接口要好。一個接口應該僅代表一個角色,而不應該把所有的操作都封裝到一個接口當中。準確地劃

分角色和其所對應的接口,不應該把沒有關係的接口合併到一起。

6。合成/聚合複用原則

聚合: 表示擁有或整體與部分的關係。
合成:更強的聚合關係。整體負責部分的生命週期,整體和部分是不可分的,部分是不能被共享的。比如孫悟空 ,他的四肢, 和他的武器。

悟空和四肢的關係就是合成,而和武器之間的關係就是聚合。

在面向對象中,有繼承和合成/聚合兩種基本服用方法。合成/聚合是將已有對象作爲自己的成員,新對象調用對象已有的功能。這有很多優點:
1) 這種複用是黑箱操作,把成員對象的細節封裝起來。
2)這種複用可以動態的改變,新對象可以動態的引用其他的同類對象。

繼承複用有如下的優點和缺點。
1)容易實現。
2)繼承複用破壞了包裝,將超類的實現細節暴露給子類。
3)同時如果超類發生改變,子類也不得不跟着改變。
4)繼承是靜態的。

儘量使用和成/聚合而不是繼承來實現複用。而區分這兩種關係,區分”Has-A”和“Is-A”的關係。能正確的區分兩者,應該就能正確的使用

這兩種複用方式。例如:人和角色。通常使用繼承,可以把每個角色作爲人的子類。如學生,僱員,經理等。但是繼承是靜態的,一旦一個人有了一個角色後就不能再擁有其他的角色。比如一個人是經理,但它也是僱員,也可能是學生。這顯然是不合理的。應該採用合成/聚合複用則。實際上人與角色是“Has-A”而不是” Is-a”的關係,並且只有當滿足里氏代換原則的時候才能使“Is-a”的關係。

在java api中 Properties 繼承 Hashtable。Proterties具有了Hashtable的所有行爲。實際上,Properties根本就不是一種Hashtable.更嚴重是把Properties可以向上轉型爲Hashtable,,繞過Properties接口,調用Hashtable的方法來對Properties操作,會導致Properties的內部矛和崩潰。他們之間可以是“Has-a”,但不能是”Is-a”的關係。在實際中,決不能因爲代碼和功能上的複用而濫用繼承,使用繼承時一定要滿足里氏代換原則。

7。迪米特法則(LoD)

迪米特法則: 一個對象應當對其他對象儘可能少的瞭解。以下是一些表述:

1) 只和你直接的朋友通信
2) 不要和陌生人講話。
3)每一個軟件單位都對其他單位只有最少的知識。

其目的就是降低各個單元的耦合,提高系統的可維護性。在模塊之間,其通信應該只通過彼此的API來通信,而不理會模塊的內部工作原理。它可以使各個模塊耦合程度降到最低,促進軟件的複用。
 
本文轉自程式先鋒網站 www.javabiz.cn
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章