組合優於繼承 物件導向原則 內聚 耦合隨感

2021-09-24 08:50:13 字數 2155 閱讀 1562

這些設計的基本目標都是為了達到易理解、易修改、易復用。

基本上,職責會發生改變的時候需要使用組合。繼承固然實現了高度復用,隨之而來的是面對變更時的不靈活。組合可以更靈活地實現職責的分配。

違反lsp的時候也需要組合,用來復用邏輯上的「父類」的**。在這種情況下,只需要復用「父類」幾個方法的**,但不需要實現其他方法。因為在這個場景下,繼承不適用(違反了lsp),就需要分離出乙個介面,然後進行組合;這也就變成了策略模式。

也就是說:

a. 類a的某個職責有type1……typen多種情況,而且會實時根據需要從typei種型別變化為typej種型別;

b. 類a需要復用類b幾個方法的**,同時不需要實現b的其他方法;

c. 類a的某個職責有type1……typen多種情況,而且會同時處於其中的多種情景。

當然,不要濫用「組合優於繼承」,能用繼承的時候還是要用繼承的。繼承有更好的語義和更清晰的結構。

介面分離isp主要是為了避免依賴不需要的介面,而產生不必要的訪問耦合;依賴倒置dip主要是為了應對變更,兩者還是有差別的。

有資料的人負責執行建立。所謂的組合和聚合關係,從本質上說,也是進行組合的物件持有的資料多。這是grasp裡的建立者模式。這是乙個動態的協作過程。

資料和行為要一致,且資料和行為要集中。這是grasp裡的資訊專家模式:把職責分配給具有完成該職責所需資訊的那個類。這是乙個靜態的職責分配過程。

適當新增輔助類來進行職責分配。比如,持久化資料,進行介面互動,這就是grasp裡的純虛構和控制器模式了。因為這些並不是真實世界(問題域)的對映,但是是真實存在的職責,就需要一些虛構的東西去承載它。其實還是詳細設計的靜態模型——職責的分配。

我甚至可以說,物件即職責,乙個物件就是乙個職責。因此,乙個物件只應該有乙個變化的原因,也就是srp了。

產生控制耦合的根本原因是職責分配不均。我與其傳遞控制標誌(flag)給另乙個物件來實現不同的行為,不如想想怎麼通過組合來實現這種行為的變化;狀態模式和策略模式都是不錯的選擇。相對於資料,控制資訊是無意義的。

訪問public的成員變數和內部類會導致內容耦合,goto語句也會。因為這相當於直接訪問了別的模組的內部,封裝完全失效。直接用編譯後的位元組碼之類的覆蓋也算,不過這也太……

公共耦合不僅來自全域性變數(共用的變數),還可能來自共用的檔案和資料,甚至是公共的裝置;這也算是公共耦合了。只要是公共的環境,就是公共耦合。

印記耦合有時候很微妙。只要沒有將傳遞的屬性全部使用,就算印記耦合,哪怕是一些無關緊要的id。而且,印記耦合必然發生在複雜的資料結構上。簡單的結構無論如何都不會產生印記耦合的。

控制耦合基本來自switch和連續的if-else。但本質上是傳遞了無意義的控制資訊。如果switch傳遞的是有用的資料,那也不算是控制耦合。

功能內聚挺玄乎的,是整個模組為了實現乙個功能,而且必須只是乙個功能。完成訂單整個功能可以是功能內聚,但是你說是不是同樣的資料同樣的過程呢?是不是順序內聚呢?但是功能內聚更高一點。

只要使用了同乙份資料,哪怕看起來風馬牛不相及的東西,也可以構成通訊內聚。比如,生成報告,儲存報告,列印報告三個功能,看起來其實沒什麼必然聯絡,甚至感覺像是邏輯內聚,但因為都操作了報告的資料,所以就是通訊內聚。

初始化是時間內聚。只要是初始化就是,這一條優先順序很高。

一段**不一定只有一種可能性。在不同的context下,可能會表現出不同的耦合性和內聚性。

內聚服從於耦合。高內聚不一定低耦合,有可能是高耦合。高內聚高耦合、低內聚低耦合是兩種經常犯的錯誤。

總結一下:

如果是初始化,或者是同時執行=>時間內聚

傳遞控制資訊的switch和連續的if-else,也就是說,根據控制訊號執行不同的行為=>邏輯內聚(因為其實是根據標誌做完全不同的事,實現不同的功能;如果只是單獨傳遞一下控制訊號,並不算邏輯內聚)

資料結構、adt=>資訊內聚

確定是同乙個功能=>功能內聚

不能確定是不是乙個功能,或者已經確定不是乙個功能的情況下:

如果操作同乙份資料且有順序=>順序內聚(通訊+過程);雖然優先順序高,但很模糊,需要慎重

如果操作同乙份資料但沒有順序=>通訊內聚

如果不止乙份資料,但是有順序(同乙個問題)=>過程內聚

毫無關聯=>偶然內聚

需要強調的是,上面提到的資料,不是簡單的變數;一般是成員變數,或者是全域性共享的屬性。全域性變數帶來的公共耦合不在這次的討論範圍內。

Python 物件導向 繼承 組合

1.組合將自定義類的物件作為類的屬性class teacher def init self,name self.name name class student def init self,name,teacher self.name name self.teacher teacher tec tea...

物件導向繼承 寄生式組合繼承

2.子類建構函式 function ministudent name,age,混合繼承 物件冒充 建構函式中屬性和方法 原型鏈繼承 繼承原型物件中屬性和方法 4.原型鏈繼承 object.create 以原型為基礎建立物件 ministudent.prototype object.create st...

python 物件導向 組合與繼承

1 組合是使用其他的類例項作為自己的乙個屬性 has a關係 class doginfo def init self,name,age self.name name self.age age def p info self print name is age is format self.name,...