本筆記摘抄自:http://www.javashuo.com/article/p-qcqmitdp-hn.html,記錄一下學習過程以備後續查用。html
寫代碼也是有原則的,咱們之因此使用設計模式,主要是爲了適應變化,提升代碼複用率,使軟件更具備可維護性和可擴展性。若是咱們能更好的理編程
解這些設計原則,對咱們理解面向對象的設計模式也是有幫助的,由於這些模式的產生是基於這些原則的。設計模式
設計原則包括:單一職責原則(SRP)、開閉原則(OCP)、里氏替換原則(LSP)、依賴倒置原則(DIP)、接口隔離原則(ISP)、合成複用原學習
則(CRP)、迪米特法則(LoD)。編碼
下面咱們就分別介紹這七種設計原則:設計
1、單一職責原則(SRP)htm
1)SRP(Single Responsibilities Principle)的定義:就一個類而言,應該僅有一個引發它變化的緣由。簡而言之,就是功能要單一。對象
2)若是一個類承擔的職責過多,就等於把這些職責耦合在一塊兒,一個職責的變化可能會削弱或者抑制這個類完成其它職責的能力。這種耦合會致使blog
脆弱的設計,當變化發生時,設計會遭受到意想不到的破壞。(敏捷軟件開發)繼承
3)軟件設計真正要作的許多內容,就是發現職責並把那些職責相互分離。
小結:單一職責原則(SRP)能夠看作是低耦合、高內聚在面向對象原則上的引伸,將職責定義爲引發變化的緣由,以提升內聚性來減小引發變化的
緣由。責任過多,引發它變化的緣由就越多,這樣就會致使職責依賴,大大損傷其內聚性和耦合度。
2、開閉原則(OCP)
1)OCP(Open-Close Principle)的定義:就是說軟件實體(類、方法等等)應該能夠擴展(擴展能夠理解爲增長),可是不能在原來的方法或者類上修
改,也能夠這樣說,對增長代碼開放,對修改代碼關閉。
2)OCP的兩個特徵: 對於擴展(增長)是開放的,由於它不影響原來的,這是新增長的。對於修改是封閉的,若是老是修改,邏輯會愈來愈複雜。
小結:開閉原則(OCP)是面向對象設計的核心思想。遵循這個原則能夠爲咱們面向對象的設計帶來巨大的好處:可維護(維護成本小、作管理簡
單、影響最小)、可擴展(有新需求,增長就好)、可複用(不耦合,可使用之前代碼)、靈活性好(維護方便、簡單)。開發人員應該僅對程序中
出現頻繁變化的那些部分作出抽象(可是不能過激,對應用程序中的每一個部分都刻意地進行抽象一樣也不是一個好主意,拒毫不成熟的抽象和抽象自己
同樣重要)。
3、里氏替換原則(LSP)
1)LSP(Liskov Substitution Principle)的定義:子類型必須可以替換掉它們的父類型。更直白的說,LSP是實現面向接口編程的基礎。
小結:任何基類能夠出現的地方,子類必定能夠出現,因此咱們能夠實現面向接口編程。 LSP是繼承複用的基石,只有當子類能夠替換掉基類,軟件
的功能不受到影響時,基類才能真正被複用,而子類也可以在基類的基礎上增長新的行爲。里氏代換原則是對開閉原則的補充,實現開閉原則的關鍵步
驟就是抽象化,而基類與子類的繼承關係就是抽象化的具體實現,因此里氏代換原則是對實現抽象化的具體步驟的規範。
里氏替換原則的經典反例:正方形不是長方形、玩具槍不能殺人、鴕鳥不會飛。
4、依賴倒置原則(DIP)
1)DIP(Dependence Inversion Principle)的定義:抽象不該該依賴細節,細節應該依賴於抽象。簡單說就是,咱們要針對接口編程,而不要針對實現
編程。
2)高層模塊不該該依賴低層模塊,兩個都應該依賴抽象,由於抽象是穩定的。抽象不該該依賴具體(細節),具體(細節)應該依賴抽象。
小結:依賴倒置原則其實能夠說是面向對象設計的標誌,若是在咱們編碼的時候考慮的是面向接口編程,而不是簡單的功能實現,體現了抽象的穩定
性,只有這樣才符合面向對象的設計。
5、接口隔離原則(ISP)
1)接口隔離原則(Interface Segregation Principle, ISP)指的是使用多個專門的接口比使用單一的總接口要好。也就是說不要讓一個單一的接口承擔
過多的職責,而應把每一個職責分離到多個專門的接口中,進行接口分離,過於臃腫的接口是對接口的一種污染。
2)使用多個專門的接口比使用單一的總接口要好。
3)一個類對另一個類的依賴性應當是創建在最小的接口上的。
4)一個接口表明一個角色,不該當將不一樣的角色都交給一個接口。沒有關係的接口合併在一塊兒,造成一個臃腫的大接口,這是對角色和接口的污染。
5)「不該該強迫客戶依賴於它們不用的方法。接口屬於客戶,不屬於它所在的類層次結構。」這個說得很明白了,再通俗點說,不要強迫客戶使用它們
不用的方法,若是強迫用戶使用它們不使用的方法,那麼這些客戶就會面臨因爲這些不使用的方法的改變所帶來的改變。
小結:接口隔離原則(ISP)告訴咱們,在作接口設計的時候,要儘可能設計的接口功能單一,功能單一,使它變化的因素就少,這樣就更穩定。其實這
體現了高內聚、低耦合的原則,這樣作也避免接口的污染。
6、合成複用原則(CRP)
1)組合複用原則(Composite Reuse Principle, CRP)就是在一個新的對象裏面使用一些已有的對象,使之成爲新對象的一部分,新對象經過向這些
對象的委派達到複用已用功能的目的。簡單地說,就是要儘可能使用合成/聚合,儘可能不要使用繼承。
2)要使用好組合複用原則,首先須要區分」Has--A」和「Is--A」的關係。「Is--A」是指一個類是另外一個類的「一種」,是屬於的關係,而「Has--A」則不一樣,它表
示某一個角色具備某一項責任。致使錯誤的使用繼承而不是聚合的常見的緣由是錯誤地把「Has--A」當成「Is--A」。例如:雞是動物,這就是「Is-A」的表現,
某人有一支手槍,People類型裏面包含一個Gun類型,這就是「Has-A」的表現。
小結:合成複用原則可使系統更加靈活,類與類之間的耦合度下降,一個類的變化對其餘類形成的影響相對較少,所以通常首選使用合成來實現復
用;其次才考慮繼承,在使用繼承時,須要嚴格遵循里氏替換原則,有效使用繼承會有助於對問題的理解,下降複雜度,而濫用繼承反而會增長系統構
建和維護的難度以及系統的複雜度,所以須要慎重使用繼承複用。
7、迪米特法則(Law of Demeter)
1)迪米特法則(Law of Demeter,LoD)又叫最少知識原則(Least Knowledge Principle,LKP),指的是一個對象應當對其餘對象有儘量少的了
解。也就是說,一個模塊或對象應儘可能少的與其餘實體之間發生相互做用,使得系統功能模塊相對獨立,這樣當一個模塊修改時,影響的模塊就會越少,
擴展起來更加容易。
2)關於迪米特法則其餘的一些表述有:只與你直接的朋友們通訊,不要跟「陌生人」說話。
3)外觀模式(Facade Pattern)和中介者模式(Mediator Pattern)就使用了迪米特法則。
小結:迪米特法則的初衷是下降類之間的耦合,實現類型之間的高內聚、低耦合,這樣能夠解耦。可是凡事都有度,過度的使用迪米特原則,會產生
大量這樣的中介和傳遞類,致使系統複雜度變大。因此在採用迪米特法則時要反覆權衡,既作到結構清晰,又要高內聚低耦合。