前章 Caché 程序員必須知道的七大原則

單一職責原則

定義

  • 就一個類而言,應該僅有一個引起它變化的原因。

  • 如果一個類承擔的職責過多,就等於把這些職責耦合在一起,一個職責的變化可能會消弱或者抑制這個類完成其他職責的能力。

  • 這種耦合會導致脆弱的設計,當變化發生時,設計會遭受到意想不到的破壞。

判斷

  • 如果你能夠想到多於一個的動機去改變一個類,那麼這個類就具有多於一個的職責。

反例

反例一:

ClassMethod Filter(flag)
{
    q:(flag'=0)&&(..First())
    q:(flag=0)&&(..Second())
    q:(..Third())
}

反例二:

ClassMethod GetStr()
{
	s str1 = ""		
	s str2 = ""			
	f i = 1 : 1 :100 d
	.s str1 = str1 + i
	.s str2 = str2 + i
	q 
}

正例

正例一:

ClassMethod FirstFilter()
{
    q:(..First())
    q:(..Third())
}
ClassMethod SecondFilter()
{
    q:(..Second())
    q:(..Third())
}
ClassMethod CommonFilter()
{
    q:(..Third())
}

正例二:

ClassMethod GetStr1()
{
	s str1 = ""		
	f i = 1 : 1 :10 d
	.s str1 = str1 + i
	q 
}
ClassMethod GetStr2()
{
	s str2 = ""			
	f i = 1 : 1 :10 d
	.s str2 = str2 + i
	q 
}

有人會問:正例二,這種明明可以一次循環就可以獲取變量str1,str2,分成了2次降低了程序效率。但是如果業務邏輯複雜str1,str2,往往要經過循環裏的各種處理纔會得到。所以在一定可控的效率範圍內,犧牲一點點效率,換取代碼的複用性可維護性是值得的。

開放-封閉原則

定義

軟件實體(類,模塊,函數,等等)應該可以拓展,但是不可修改。

  • 對於拓展是開放的。
  • 對於更改是封閉的。

現實

  • 絕對的修改關閉是不可能的。無論模塊是多麼的“封閉”,都會存在一些無法對之封閉的變化。

  • 既然不可能完全封閉,設計人員必須對於他設計的模塊應該對哪種變化封閉做出選擇。

  • 他應該先猜測出最有可能發生的變化種類,然後構造抽象來給那些變化。

應對

  • 在我們最初編寫代碼時,假設變化不會發生。當變化發生時,我們就創建抽象來隔離以後發生的同類變化。

  • 比如,第一章簡單工廠模式的需求,加法算法。當需要再增加一個減法時,需要修改原來這個類,這就違背了 開放-封閉原則 ,於是你就該考慮重構程序,增加一個抽象的運算類,通過一些面向對象的手段,繼承,多態來隔離加法,減法的耦合程度

  • 面對需求,對程序的改動是通過增加新代碼進行的,而不是更改現有的代碼。

  • 我們希望的是在開發工作展開就知道可能發生的變化。查明可能發生的變化所等待的時間越長,要創建正確的抽象就越困。所以詳細設計一定要覆蓋全面。

依賴顛倒原則

定義

  • 高層模塊不應該依賴低層模塊。兩個都應該依賴抽象。
  • 抽象不應該依賴細節,細節應該依賴抽象。
  • 通俗講,針對接口編程,不要對實現編程。

舉例

  • 電腦CPU,內存,主板,都是可插拔式。針對統一接口,設計不用的硬件。配件壞了直接換掉即可。
  • 錄音機,強耦合,出問題,也不好定位。好比寫程序都混在一起,找出錯誤非常困難。

里氏替換原則

定義

  • 子類型必須能夠替換掉他們的父類型
    一個軟件實體如果使用的是一個父類,那麼一定適用於其子類,而且他觀察不出父類對象和子類對象區別。也就是說,在軟件裏面,把父類都替換成它的子類,程序的行爲沒有變化。

  • 子類可以實現父類的抽象方法,但不能覆蓋父類的非抽象方法;

  • 子類中可以增加自己特有的方法;

  • 子類的方法重載父類的方法時,輸入參數要比父類方法的輸入參數更寬鬆。

多態的表現

迪米特法則

定義

  • 如果兩個類不必彼此直接通信,那麼這兩個類就不應當發生直接的相互作用。如果其中一個類需要調用另一個類的某一個方法的話,可以通過第三者轉發這個調用。

  • 在類的結構設計上,每一個類都應當儘量降低成員的訪問權限,也就是說,一個類包裝好自己的private狀態,不需要讓別的類知道的字段或行爲就不要公開。

  • 迪米特法則其根本思想是強調了類之間的鬆耦合。

  • 類之間的耦合越弱,越有利於複用,一個處於弱耦合的類被修改,不會對有關係的類造成波及。

接口隔離原則

定義

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

缺點

  • 接口粒度太大,靈活低。
  • 接口粒度太小,導致接口數量劇增

合成/聚合複用原則

  • 集合表示一種弱的擁有關係,體現的是A對象可以包含B對象,但B對象不是A對象的一部分。
  • 合成則是一種強的擁有關係,體現了嚴格的部分和整體關係,部分和整體的生命週期一樣。
  • 繼承是一種強耦合的結構。父類變,子類就必須要變。

有點

優先使用對象的合成/聚合將有助於你保持每個類被封裝,並被集中在單個任務上,這樣類和類繼承層次保持較小規模,並且不太可能增長爲不可控制的龐然大物、

示例

例如,大雁有兩個翅膀,翅膀與大雁是部分和整體的關係,並且他們的生命週期是相同的,於是大雁和翅膀就是合成關係。而大雁是羣居動物,所以每隻大雁都屬於一個雁羣,一個雁羣可以有多隻大雁,所以大雁與雁羣是聚合關係。

初識UML類圖

一張圖帶帶你理解UML類圖關係。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Krl5pdv5-1588555580558)(1CB5C8E2433B4520B4BA024162234436)]

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