(GOF23設計模式)一,代碼設計的基本原則

類之間的關係

根據類與類之間的耦合度從弱到強排列,UML 中的類圖有以下幾種關係:依賴關係、關聯關係、聚合關係、組合關係、泛化關係和實現關係。其中泛化和實現的耦合度相等,它們是最強的。

依賴關係

某個類的方法通過局部變量、方法的參數或者對靜態方法的調用來訪問另一個類(被依賴類)中的某些方法來完成一些職責

關聯關係

一般關聯關係

一個類的對象作爲另一個類的成員變量來實現關聯關係

聚合關係

強關聯關係,是 has-a 的關係
聚合關係也是通過成員對象來實現的,其中成員對象是整體對象的一部分,但是成員對象可以脫離整體對象而獨立存在。例如,學校與老師的關係,學校包含老師,但如果學校停辦了,老師依然存在。

組合關係

表示類之間的整體與部分的關係,但它是一種更強烈的聚合關係,是 cxmtains-a 關係。
在組合關係中,整體對象可以控制部分對象的生命週期,一旦整體對象不存在,部分對象也將不存在,部分對象不能脫離整體對象而存在。例如,頭和嘴的關係,沒有了頭,嘴也就不存在了。

開閉原則

定義:軟件實體應當對擴展開放,對修改關閉

這裏的軟件實體包括以下幾個部分:
  1. 項目中劃分出的模塊
  2. 類與接口
  3. 方法

里氏替換原則

定義:繼承必須確保超類所擁有的性質在子類中仍然成立

子類可以擴展父類的功能,但不能改變父類原有的功能
也就是說:子類繼承父類時,除添加新的方法完成新增功能外,儘量不要重寫父類的方法。

里氏替換原則的主要作用如下:
  1. 里氏替換原則是實現開閉原則的重要方式之一。
  2. 它克服了繼承中重寫父類造成的可複用性變差的缺點。
  3. 它是動作正確性的保證。即類的擴展不會給已有的系統引入新的錯誤,降低了代碼出錯的可能性。

依賴倒置原則

定義:高層模塊不應該依賴低層模塊,兩者都應該依賴其抽象;抽象不應該依賴細節,細節應該依賴抽象

核心思想是:要面向接口編程,不要面向實現編程。

依賴倒置原則是實現開閉原則的重要途徑之一,它降低了客戶與實現模塊之間的耦合。

依賴、倒置原則的作用
  • 依賴倒置原則可以降低類間的耦合性。
  • 依賴倒置原則可以提高系統的穩定性。
  • 依賴倒置原則可以減少並行開發引起的風險。
  • 依賴倒置原則可以提高代碼的可讀性和可維護性。

單一職責原則 又稱單一功能原則

這裏的職責是指類變化的原因,單一職責原則規定一個類應該有且僅有一個引起它變化的原因,否則類應該被拆分

該原則提出對象不應該承擔太多職責,如果一個對象承擔了太多的職責,至少存在以下兩個缺點:
  1. 一個職責的變化可能會削弱或者抑制這個類實現其他職責的能力;
  2. 當客戶端需要該對象的某一個職責時,不得不將其他不需要的職責全都包含進來,從而造成冗餘代碼或代碼的浪費。
單一職責原則的優點
  • 降低類的複雜度。一個類只負責一項職責,其邏輯肯定要比負責多項職責簡單得多。
  • 提高類的可讀性。複雜性降低,自然其可讀性會提高。
  • 提高系統的可維護性。可讀性提高,那自然更容易維護了。
  • 變更引起的風險降低。變更是必然的,如果單一職責原則遵守得好,當修改一個功能時,可以顯著降低對其他功能的影響。

接口隔離原則

定義一:客戶端不應該被迫依賴於它不使用的方法

定義二:一個類對另一個類的依賴應該建立在最小的接口上

接口隔離原則和單一職責原則的區別

  1. 單一職責原則注重的是職責,而接口隔離原則注重的是對接口依賴的隔離。
  2. 單一職責原則主要是約束類,它針對的是程序中的實現和細節;接口隔離原則主要約束接口,主要針對抽象和程序整體框架的構建。

接口隔離原則的優點

接口隔離原則是爲了約束接口、降低類對接口的依賴性,遵循接口隔離原則有以下 5 個優點。
  1. 將臃腫龐大的接口分解爲多個粒度小的接口,可以預防外來變更的擴散,提高系統的靈活性和可維護性。
  2. 接口隔離提高了系統的內聚性,減少了對外交互,降低了系統的耦合性。
  3. 如果接口的粒度大小定義合理,能夠保證系統的穩定性;但是,如果定義過小,則會造成接口數量過多,使設計複雜化;如果定義太大,靈活性降低,無法提供定製服務,給整體項目帶來無法預料的風險。
  4. 使用多個專門的接口還能夠體現對象的層次,因爲可以通過接口的繼承,實現對總接口的定義。
  5. 能減少項目工程中的代碼冗餘。過大的大接口裏面通常放置許多不用的方法,當實現這個接口的時候,被迫設計冗餘的代碼。

接口隔離原則的實現方法

  1. 接口儘量小,但是要有限度。一個接口只服務於一個子模塊或業務邏輯。
  2. 爲依賴接口的類定製服務。只提供調用者需要的方法,屏蔽不需要的方法。
  3. 瞭解環境,拒絕盲從。每個項目或產品都有選定的環境因素,環境不同,接口拆分的標準就不同深入瞭解業務邏輯。
  4. 提高內聚,減少對外交互。使接口用最少的方法去完成最多的事情。

迪米特法則

定義:又叫作最少知識原則,只與你的直接朋友交談,不跟“陌生人”說話

其含義是:如果兩個軟件實體無須直接通信,那麼就不應當發生直接的相互調用,可以通過第三方轉發該調用。其目的是降低類之間的耦合度,提高模塊的相對獨立性。

“朋友”是指:當前對象本身、當前對象的成員對象、當前對象所創建的對象、當前對象的方法參數等,這些對象同當前對象存在關聯、聚合或組合關係,可以直接訪問這些對象的方法。

迪米特法則的優點

  1. 降低了類之間的耦合度,提高了模塊的相對獨立性。
  2. 由於親合度降低,從而提高了類的可複用率和系統的擴展性。

但是,過度使用迪米特法則會使系統產生大量的中介類,從而增加系統的複雜性,使模塊之間的通信效率降低。所以,在釆用迪米特法則時需要反覆權衡,確保高內聚和低耦合的同時,保證系統的結構清晰。

迪米特法則的實現方法

  1. 從依賴者的角度來說,只依賴應該依賴的對象。
  2. 從被依賴者的角度說,只暴露應該暴露的方法。

運用迪米特法則時要注意以下 6 點。

  1. 在類的劃分上,應該創建弱耦合的類。類與類之間的耦合越弱,就越有利於實現可複用的目標。
  2. 在類的結構設計上,儘量降低類成員的訪問權限。
  3. 在類的設計上,優先考慮將一個類設置成不變類。
  4. 在對其他類的引用上,將引用其他對象的次數降到最低。
  5. 不暴露類的屬性成員,而應該提供相應的訪問器(set 和 get 方法)。
  6. 謹慎使用序列化(Serializable)功能。

合成複用原則,又叫組合/聚合複用原則

定義:它要求在軟件複用時,要儘量先使用組合或者聚合等關聯關係來實現,其次才考慮使用繼承關係來實現。

如果要使用繼承關係,則必須嚴格遵循里氏替換原則

合成複用原則同里氏替換原則相輔相成的,兩者都是開閉原則的具體實現規範。

合成複用原則的重要性

這本書看到現在唯一一個強調重要性的原則

通常類的複用分爲繼承複用和合成複用兩種,繼承複用雖然有簡單和易實現的優點,但它也存在以下缺點。
  1. 繼承複用破壞了類的封裝性。因爲繼承會將父類的實現細節暴露給子類,父類對子類是透明的,所以這種複用又稱爲“白箱”複用。
  2. 子類與父類的耦合度高。父類的實現的任何改變都會導致子類的實現發生變化,這不利於類的擴展與維護。
  3. 它限制了複用的靈活性。從父類繼承而來的實現是靜態的,在編譯時已經定義,所以在運行時不可能發生變化。
採用組合或聚合複用時,可以將已有對象納入新對象中,使之成爲新對象的一部分,新對象可以調用已有對象的功能,它有以下優點:
  1. 它維持了類的封裝性。因爲成分對象的內部細節是新對象看不見的,所以這種複用又稱爲“黑箱”複用。
  2. 新舊類之間的耦合度低。這種複用所需的依賴較少,新對象存取成分對象的唯一方法是通過成分對象的接口。
  3. 複用的靈活性高。這種複用可以在運行時動態進行,新對象可以動態地引用與成分對象類型相同的對象。

合成複用原則的實現方法:

合成複用原則是通過將已有的對象納入新對象中,作爲新對象的成員對象來實現的,新對象可以調用已有對象的功能,從而達到複用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章