裏式替換原則(Liskov Substitution Principle,LSP),全部引用基類的地方必須可以透明的使用其子類對象。也就是說,只要父類出現的地方都能替換爲子類,不會產生異常。可是反過來,子類出現的地方,替換爲父類就可能出現問題。 也就是子類能夠擴展父類的功能,但不能改變父類的功能。 通俗的講:類須要擴展功能時,新類繼承舊類,使用新類替換舊類不會形成故障。
1. 子類能夠實現父類的抽象方法,但不能覆蓋父類的非抽象方法;
2. 子類中能夠增長本身持有的方法;
3. 當子類的方法重載父類的方法時,方法的前置條件(即方法的形參)要比父類方法的輸入參數更寬鬆;
4. 當子類的方法實現父類的抽象方法是,方法的後置條件(即方法的返回值)要比父類更嚴格。html
單一職責原則(Single Responsibility Principle, SRP),
There should never be more than one reason for a class to change. (應該有且僅有一個緣由引發類的變動)
如下摘自:http://blog.csdn.net/vebasan/article/details/8003102
有時候,開發人員設計接口的時候,將用戶的屬性和用戶的行爲放在一個接口中聲明。這就形成業務對象和業務邏輯放在一塊兒了。
例子:web
public interface Itutu { //height void setHeight(double height); void getHeight(); //weight void setWeight(double weight); void getWeight(); //eat void eat(boolean hungry); //surf in internet void internet(boolean buy); }
單一職責的意義
1. 下降類的複雜性,實現什麼樣的職責都有清晰的定義;
2. 提升可讀性和可維護性;
3. 下降變動引發的風險,對系統擴展性和維護性頗有幫助。編程
依賴倒置原則(Dependency Inversion Principle, DIP)
Definition: High level modules should not depend upon low level modules, Both should depend upon abstractions. Abstractions should not depend upon details, details should depend upon abstractions.框架
即:高層模塊不該該依賴低層模塊,兩者都應該依賴其抽象。抽象不該該依賴細節,細節應該依賴抽象。工具
抽象:即抽象類或接口,是不可以實例化的。this
細節:即具體的實現類,實現接口或者繼承抽象類所產生的類,能夠經過關鍵字new直接被實例化。spa
每個邏輯的實現都是由原子邏輯組成的,不可分割的原子邏輯就是低層模塊,原子邏輯的再組裝就是高層模塊。.net
面向接口編程
如下摘自:http://www.cnblogs.com/cbf4life/archive/2009/12/15/1624435.html設計
講了這麼多,估計你們對「倒置」這個詞仍是有點不理解,那到底什麼是「倒置」呢?咱們先說「正置」是什麼意思,依賴正置就是類間的依賴是實實在在的實現類間的依賴,也就是面向實現編程,這也是正常人的思惟方式,我要開奔馳車就依賴奔馳車,我要使用筆記本電腦就直接依賴筆記本電腦,而編寫程序須要的是對現實世界的事物進行抽象,抽象的結果就是有了抽象類和接口,而後咱們根據系統設計的須要產生了抽象間的依賴,代替了人們傳統思惟中的事物間的依賴,「倒置」就是從這裏產生的。code
依賴倒轉原則的本質就是經過抽象(接口或抽象類)使各個類或模塊的實現彼此獨立,不互相影響,實現模塊間的鬆耦合,咱們怎麼在項目中使用這個規則呢?只要遵循如下的幾個規則就能夠:
每一個類儘可能都有接口或抽象類,或者抽象類和接口二者都具有。
這是依賴倒置的基本要求,接口和抽象類都是屬於抽象的,有了抽象纔可能依賴倒置。
變量的顯示類型儘可能是接口或者是抽象類。
不少書上說變量的類型必定要是接口或者是抽象類,這個有點絕對化了,好比一個工具類,xxxUtils通常是不須要接口或是抽象類的。還有,若是你要使用類的clone方法,就必須使用實現類,這個是JDK提供一個規範。
任何類都不該該從具體類派生。
若是一個項目處於開發狀態,確實不該該有從具體類派生出的子類的狀況,但這也不是絕對的,由於人都是會犯錯誤的,有時設計缺陷是在所不免的,所以只要不超過兩層的繼承都是能夠忍受的。特別是作項目維護的同志,基本上能夠不考慮這個規則,爲何?維護工做基本上都是作擴展開發,修復行爲,經過一個繼承關係,覆寫一個方法就能夠修正一個很大的Bug,何須再要去繼承最高的基類呢?
儘可能不要覆寫基類的方法。
若是基類是一個抽象類,並且這個方法已經實現了,子類儘可能不要覆寫。類間依賴的是抽象,覆寫了抽象方法,對依賴的穩定性會產生必定的影響。
抽象層肯定後再也不修改。經過抽象層導出多個新的具體類實現擴展。
客戶端不該該不依賴它不須要的接口,一個類對另外一個類的依賴應該創建在最小的接口上。使用多個專門的接口比使用單一的總接口要好。
一個類對另一個類的依賴性應當是創建在最小的接口上的。
一個接口表明一個角色,不該當將不一樣的角色都交給一個接口。沒有關係的接口合併在一塊兒,造成一個臃腫的大接口,這是對角色和接口的污染。
「不該該強迫客戶依賴於它們不用的方法。接口屬於客戶,不屬於它所在的類層次結構。」這個說得很明白了,再通俗點說,不要強迫客戶使用它們不用的方法,若是強迫用戶使用它們不使用的方法,那麼這些客戶就會面臨因爲這些不使用的方法的改變所帶來的改變。
接口隔離原則的含義是:創建單一接口,不要創建龐大臃腫的接口,儘可能細化接口,接口中的方法儘可能少。也就是說,咱們要爲各個類創建專用的接口,而不要試圖去創建一個很龐大的接口供全部依賴它的類去調用。本文例子中,將一個龐大的接口變動爲3個專用的接口所採用的就是接口隔離原則。在程序設計中,依賴幾個專用的接口要比依賴一個綜合的接口更靈活。接口是設計時對外部設定的「契約」,經過分散定義多個接口,能夠預防外來變動的擴散,提升系統的靈活性和可維護性。
說到這裏,不少人會覺的接口隔離原則跟以前的單一職責原則很類似,其實否則。其一,單一職責原則原注重的是職責;而接口隔離原則注重對接口依賴的隔離。其二,單一職責原則主要是約束類,其次纔是接口和方法,它針對的是程序中的實現和細節;而接口隔離原則主要約束接口接口,主要針對抽象,針對程序總體框架的構建。
採用接口隔離原則對接口進行約束時,要注意如下幾點:
接口儘可能小,可是要有限度。對接口進行細化能夠提升程序設計靈活性是不掙的事實,可是若是太小,則會形成接口數量過多,使設計複雜化。因此必定要適度。
爲依賴接口的類定製服務,只暴露給調用的類它須要的方法,它不須要的方法則隱藏起來。只有專一地爲一個模塊提供定製服務,才能創建最小的依賴關係。
提升內聚,減小對外交互。使接口用最少的方法去完成最多的事情。
運用接口隔離原則,必定要適度,接口設計的過大或太小都很差。設計接口的時候,只有多花些時間去思考和籌劃,才能準確地實踐這一原則。
也稱爲最少知識原則(LeastKnowledge Principle, LKP): 一個軟件實體應當儘量少的與其餘實體發生相互做用。當一個模塊發生修改時,儘可能少地影響其餘模塊。
迪米特法則還有幾種定義形式,包括:不要和「陌生人」說話、只與你的直接朋友通訊等,在迪米特法則中,對於一個對象,其朋友包括如下幾類:(1) 當前對象自己(this);(2) 以參數形式傳入到當前對象方法中的對象;(3) 當前對象的成員對象;(4) 若是當前對象的成員對象是一個集合,那麼集合中的元素也都是朋友;(5) 當前對象所建立的對象。