設計模式之原則詳細介紹

開閉原則

開閉原則(OCP)是面向對象設計中“可複用設計”的基石,是面向對象設計中最重要的原則之一,其它很多的設計原則都是實現開閉原則的一種手段。
1988年,勃蘭特·梅耶(Bertrand Meyer)在他的著作《面向對象軟件構造(Object Oriented Software Construction)》中提出了開閉原則,它的原文是這樣:“Software entities should be open for extension,but closed for modification”。翻譯過來就是:“軟件實體應當對擴展開放,對修改關閉”。這句話說得略微有點專業,我們把它講得更通俗一點,也就是:軟件系統中包含的各種組件,例如模塊(Modules)、類(Classes)以及功能(Functions)等等,應該在不修改現有代碼的基礎上,引入新功能。開閉原則中“開”,是指對於組件功能的擴展是開放的,是允許對其進行功能擴展的;開閉原則中“閉”,是指對於原有代碼的修改是封閉的,即修改原有的代碼對外部的使用是透明的。

單一職責原則

單一職責原則(SRP:Single responsibility principle)又稱單一功能原則,面向對象五個基本原則(SOLID)之一。它規定一個類應該只有一個發生變化的原因。該原則由羅伯特·C·馬丁(Robert C. Martin)於《敏捷軟件開發:原則、模式和實踐》一書中給出的。馬丁表示此原則是基於湯姆·狄馬克(Tom DeMarco)和Meilir Page-Jones的著作中的內聚性原則發展出的。
所謂職責是指類變化的原因。如果一個類有多於一個的動機被改變,那麼這個類就具有多於一個的職責。而單一職責原則就是指一個類或者模塊應該有且只有一個改變的原因
一個類,只有一個引起它變化的原因。應該只有一個職責。每一個職責都是變化的一個軸線,如果一個類有一個以上的職責,這些職責就耦合在了一起。這會導致脆弱的設計。當一個職責發生變化時,可能會影響其它的職責。另外,多個職責耦合在一起,會影響複用性。例如:要實現邏輯和界面的分離。

里氏替換原則

里氏替換原則(Liskov Substitution Principle LSP)面向對象設計的基本原則之一。 里氏替換原則中說,任何基類可以出現的地方,子類一定可以出現。 LSP是繼承複用的基石,只有當衍生類可以替換掉基類,軟件單位的功能不受到影響時,基類才能真正被複用,而衍生類也能夠在基類的基礎上增加新的行爲。
如此,問題產生了:“我們如何去度量繼承關係的質量?”
Liskov於1987年提出了一個關於繼承的原則“Inheritance should ensure that any property proved about supertype objects also holds for subtype objects.”——“繼承必須確保超類所擁有的性質在子類中仍然成立。”也就是說,當一個子類的實例應該能夠替換任何其超類的實例時,它們之間才具有is-A關係。
該原則稱爲Liskov Substitution Principle——里氏替換原則。林先生在上課時風趣地稱之爲“老鼠的兒子會打洞”。^_^

依賴倒置原則

依賴倒置原則(Dependence Inversion Principle)是程序要依賴於抽象接口,不要依賴於具體實現。簡單的說就是要求對抽象進行編程,不要對實現進行編程,這樣就降低了客戶與實現模塊間的耦合。
一個應用中的重要策略決定及業務模型正是在這些高層的模塊中。也正是這些模型包含着應用的特性。但是,當這些模塊依賴於低層模塊時,低層模塊的修改將會直接影響到它們,迫使它們也去改變。這種境況是荒謬的。應該是處於高層的模塊去迫使那些低層的模塊發生改變。應該是處於高層的模塊優先於低層的模塊。無論如何高層的模塊也不應依賴於低層的模塊。而且,我們想能夠複用的是高層的模塊。通過子程序庫的形式,我們已經可以很好地複用低層的模塊了。當高層的模塊依賴於低層的模塊時,這些高層模塊就很難在不同的環境中複用。但是,當那些高層模塊獨立於低層模塊時,它們就能很簡單地被複用了。這正是位於框架設計的最核心之處的原則。

接口隔離原則

接口隔離原則(ISP–Interface Segregation Principle)使用多個專門的接口比使用單一的總接口要好。
一個類對另外一個類的依賴性應當是建立在最小的接口上的。
一個接口代表一個角色,不應當將不同的角色都交給一個接口。沒有關係的接口合併在一起,形成一個臃腫的大接口,這是對角色和接口的污染。
“不應該強迫客戶依賴於它們不用的方法。接口屬於客戶,不屬於它所在的類層次結構。”這個說得很明白了,再通俗點說,不要強迫客戶使用它們不用的方法,如果強迫用戶使用它們不使用的方法,那麼這些客戶就會面臨由於這些不使用的方法的改變所帶來的改變。

組合/聚合複用原則

組合/聚合複用原則(Composite/Aggregate Reuse Principle CARP).組合和聚合都是對象建模中關聯(Association)關係的一種.聚合表示整體與部分的關係,表示“含有”,整體由部分組合而成,部分可以脫離整體作爲一個獨立的個體存在。組合則是一種更強的聚合,部分組成整體,而且不可分割,部分不能脫離整體而單獨存在。在合成關係中,部分和整體的生命週期一樣,組合的新的對象完全支配其組成部分,包括他們的創建和銷燬。一個合成關係中成分對象是不能與另外一個合成關係共享。
組合/聚合和繼承是實現複用的兩個基本途徑。合成複用原則是指儘量使用合成/聚合,而不是使用繼承。
只有當以下的條件全部被滿足時,才應當使用繼承關係。
子類是超類的一個特殊種類,而不是超類的一個角色,也就是區分“Has-A”和“Is-A”.只有“Is-A”關係才符合繼承關係,“Has-A”關係應當使用聚合來描述。
永遠不會出現需要將子類換成另外一個類的子類的情況。如果不能肯定將來是否會變成另外一個子類的話,就不要使用繼承。
子類具有擴展超類的責任,而不是具有置換掉或註銷掉超類的責任。如果一個子類需要大量的置換掉超類的行爲,那麼這個類就不應該是這個超類的子類。

迪米特法則

迪米特法則(Law of Demeter)又叫作最少知識原則(Least Knowledge Principle 簡寫LKP),就是說一個對象應當對其他對象有儘可能少的瞭解,不和陌生人說話。英文簡寫爲: LoD.
迪米特法則可以簡單說成:talk only to your immediate friends。 對於OOD來說,又被解釋爲下面幾種方式:一個軟件實體應當儘可能少的與其他實體發生相互作用。每一個軟件單位對其他的單位都只有最少的知識,而且侷限於那些與本單位密切相關的軟件單位。
迪米特法則的初衷在於降低類之間的耦合。由於每個類儘量減少對其他類的依賴,因此,很容易使得系統的功能模塊功能獨立,相互之間不存在(或很少有)依賴關係。
迪米特法則不希望類之間建立直接的聯繫。如果真的有需要建立聯繫,也希望能通過它的友元類來轉達。因此,應用迪米特法則有可能造成的一個後果就是:系統中存在大量的中介類,這些類之所以存在完全是爲了傳遞類之間的相互調用關係——這在一定程度上增加了系統的複雜度。
有興趣可以研究一下設計模式的門面模式(Facade)和中介模式(Mediator),都是迪米特法則應用的例子。
值得一提的是,雖然Ian Holland對計算機科學的貢獻也僅限於這一條法則,其他方面的建樹不多,但是,這一法則卻不僅僅侷限於計算機領域,在其他領域也同樣適用。比如,美國人就在航天系統的設計中採用這一法則。

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