【設計模式】漫談六大原則
六大原則的起因:面向物件中封裝、繼承、多型三大支柱蘊含了用抽象來封裝變化,降低耦合,實現複用的精髓。
封裝:隱藏內部實現,保護內部資訊。
繼承:實現複用,歸納共性。
多型:改寫物件行為,實現更高級別的繼承。
要實現這些目的,就必須遵守一些原則:封裝變化、對介面程式設計、少繼承多聚合等等總結這些,歸納出六大原則
單一職責原則(SRP)
定義:就一個類而言,應該僅有一個引起它變化的原因。
翻譯:一個類只有一個職責。
如果一個類承擔的職責過多,就等於把這些職責耦合在一起,一個職責的變化可能會削弱或者抑制這個類完成其他職責的能力。這種耦合會導致脆弱的設計。當變化發生時,設計會遭受到意想不到的破壞。
軟體設計真正要做的許多內容,就是發現職責並把那些職責相互分離。
如果你能想到多餘一個的動機去改變一個類,那這個類就具有多餘一個的職責。
開放-封閉原則
定義:軟體實體(類、模組、函式等等)應該可以擴充套件,但是不可修改。
這個原則的兩個特徵:對於擴充套件是開放的,對於更改是封閉的。
無論模組是多麼的‘封閉’,都會存在一些無法對之封閉的變化。既然不可能完全封閉,設計人員必須對於其他設計的模組應該對那種變化封閉做出選擇。他必須先猜測出最優可能發生的變化種類,然後構造抽象來隔離那些變化。
在我們最初編寫程式碼是,假設變化不會發生。當變化發生時,我們就建立抽象來隔離以後發生的同類變化。
面對需求,對程式的改動是通過增加新程式碼進行的,而不是更改現有的程式碼。
開放-封閉原則是面向物件設計的核心所在。遵循這個原則可以帶來面向物件技術所聲稱的巨大好處,也就是可維護、可擴充套件、可複用、靈活性好。開發人員應該僅對程式中呈現出頻繁變化的那些部分作出抽象,人兒,對於應用程式中的每個部分都可以地進行抽象同樣不是一個好主意。拒絕不成熟的抽象和抽象本身一樣重要。
依賴倒轉原則:
定義:A:高層模組不應該依賴低層模組。兩個都應該依賴抽象。
B: 抽象不應該依賴細節。細節應該依賴抽象。(針對介面變成,不要對實現程式設計)
依賴倒轉原則是面向物件設計的標誌,用哪種語言來編寫程式不重要,如果編寫時考慮的都是如何針對抽象程式設計而不是針對細節程式設計,即程式中所有的依賴關係都是終止於抽象類或者介面,那就是面向物件的設計,反之就是過程化的設計。
里氏代換原則(LSP)
定義:子型別必須能都替換它們的父型別。
一個軟體實體如果使用的是一個父類的話,那麼一定適用於其子類,而且它察覺不出父類物件和子類物件的區別。也就是說,在軟體裡面,把父類都替換成他的子類,程式的行為沒有變化。
只有當子類可以替換掉父類,軟體單位的功能不受到影響時,父類才能真正的複用,而子類也能夠在父類的基礎上改增加新的行為。
由於里氏代換原則,使得開放-封閉成為了可能。
由於子型別的可替代性才使得父類型別的模組在無需修改的情況下可以擴充套件。
迪米特法則(LoD)
定義:如果兩個類不必彼此直接通訊,那麼這兩個類就不應當直接的相互作用。如果其中一個類需要呼叫另一個類的某一個方法的話,可以通過第三者轉發這個呼叫。
迪米特法則的根本思想強調了類之間的鬆耦合。類之間的耦合越弱,越有利於複用,一個處在弱耦合的類被修改,不會對有關係的類造成波及。
合成/聚合複用原則(CARP)
定義:儘量使用合成/聚合,儘量不要使用類繼承。
聚合表示一種弱的‘擁有’關係,體現的是A物件可以包含B物件,但B物件不是A物件的一部分;合成則是一種強的‘擁有’關係,體現了嚴格的部分和整體的關係,部分和整體的生命週期一樣。
優先使用物件的合成/聚合將有助於你保持每個類被封裝,並被集中在單個任務上。這樣類和類繼承層次會保持較小規模,並且不太可能增長為不可控制的龐然大物。