看了設計模式這本書,簡單的記錄一下吧!java
1.單一職責原則(Single Responsibility Principle 簡稱:SRP):應該有且僅有一個緣由引發類的變動。spring
舉個簡單的例子,好比說咱們要對用戶進行操做,按照面向接口的思想,可讓IUserA接口來負責用戶的屬性,IUserB來負責用戶的行爲,而咱們只須要實現子接口IUserInfo就能夠了。要得到用戶信息時就當作IUserA的實現類,要是但願維護用戶的信息就當作IUserB的實現類就好了。編程
單一職責原則要求每一個接口職責分明、結構清晰;這樣一來,類的複雜性和接口變動引發的風險就下降了,也提升了可讀性,更容易維護了。設計模式
單一職責不只適用與接口和類,也能夠體如今方法裏面,一個方法儘量的作一件事情,固然咱們實際開發中也不會將方法的顆粒度分得很細。springboot
2.里氏替換原則(Liskov Substitution Principle 簡稱:LSP):全部引用基類的地方必須能透明的使用其子類對象。ide
假設有這樣一個場景:戰爭中士兵們都須要武器上陣殺敵,那咱們就定義War爲戰爭類,Solider爲士兵類,AbstractGun爲武器的抽象類,而後又分別有手槍類、步槍類和機槍類來繼承武器類,關係結構以下圖所示:函數
槍的主要職責是射擊,如何射擊在各個具體的子類中定義。在士兵類中定義了一個方法killEnemy(),使用武器來殺敵,那麼具體使用什麼武器,咱們在調用的時候就能夠經過setGun(AbstractGun gun)方法來設置具體是什麼槍了。能夠看到在設置士兵使用什麼武器的時候,咱們並無設置參數類型爲具體的哪種槍,只要是武器均可以上陣殺敵就好了。總結一下就是,在類中調用其餘類時務必要使用父類或接口,若是不能使用父類或接口,則說明類的設計已經違背了LSP原則。工具
有一種狀況:若是是仿真槍呢,它並非真槍實彈,也就不能實現父類的shoot()方法完成殺敵操做了,那怎麼辦呢?測試
一種就是在Solider類中增長instanceof來判斷是否是仿真槍玩具槍之類的,可是在程序中每增長一個類,全部與這個父類有關係的類都必須加判斷,很顯然是不可取的。那咱們就可讓仿真槍脫離繼承,創建一個獨立的父類與AbstractGun創建關聯委託關係,將形狀、聲音都委託給AbstractGun處理:設計
總結一下就是:若是子類不能完整的實現父類的方法,或者父類的某些方法在子類中已經發生「畸變」,則建議斷開父子關係,採用依賴、聚合、組合等關聯關係代替繼承。
3.依賴倒置(Dependence Inversion Principle 簡稱: DIP):
依賴倒置原則的原始定義包含三層:
1.高層模塊不該該依賴低層模塊,二者都應該依賴其抽象;
2.抽象不該該依賴細節;
3.細節應該依賴抽象。
高層模塊和低層容易理解,每一個邏輯的實現類都是由原子邏輯組成的,不可分割的原子邏輯就是低層模塊,原子邏輯的再組裝就是高層模塊。在java語言中,抽象就是指接口和抽象類,二者都是不能直接被實例化的;細節就是實現類,實現接口或繼承抽象類而產生的類就是細節,其特色就是能夠直接被實例化,也就是能夠加上一個關鍵字new產生一個對象。簡而言之,就是面向接口編程,模塊間的依賴經過抽象發生直接的依賴關係,其依賴關係是經過接口或抽象類產生的,接口或抽象類不依賴於實現類,而實現類依賴於接口或抽象類。
在java中,只要定義變量就必然要有類型,一個變量的類型能夠有兩種類型:表面類型和實際類型,表面類型是在定義 的時候賦予的類型,實際類型是對象的類型。
依賴的三種寫法:
1.構造函數傳遞依賴對象,在類中經過構造函數聲明依賴對象。
2.setter方法傳遞依賴對象,在抽象中設置serter方法聲明依賴關係。
3.接口聲明依賴對象。
依賴倒置原則的本質就是經過抽象(接口或實現類)使各個類或模塊的實現彼此獨立,不互相影響,實現模塊間的鬆耦合。依賴倒置原則的優勢在小型的項目中很難體現出來,其實只要記住「面向接口編程」就基本上抓住了依賴倒置原則的核心。依賴倒置原則是6個設計原則中最難實現的,它是開閉原則的重要途徑。
4.接口隔離(Interface Segreation Principle):創建單一接口,不要創建臃腫龐大的接口。
接口隔離原則和單一職責原則的審視角度是不相同的,單一職責要求的是類和接口的職責單一,注重的是職責,這是業務邏輯上的劃分,而接口隔離原則要求接口的方法儘可能少。好比把一個臃腫的接口變動爲兩個獨立的接口就能夠體現爲接口隔離原則。經過分散定義多個接口,能夠預防將來變動的擴散,提升系統的靈活性和可維護性。
使用接口隔離原則拆分接口時,首先必須知足單一職責原則:
1.接口要求高內聚:提升接口、類、模塊的處理能力,減小對外的交互,要求在接口中儘可能少公佈public方法,接口是對外的承諾,承諾越少對系統的開發越有利,變動的風險也就越少,同時也有利於下降成本。
2.定製服務:單獨爲一個個體提供優質的服務。
3.接口設計限度控制:接口的設計粒度越小,系統越靈活,可是靈活的同時也帶來告終構的複雜化,致使開發難度增長,可維護性下降。因此接口設計必定要注意適度,這也是根據本身的設計經驗和常識來判斷的。
5.迪米特法則(Law of Demeter, LOD)也稱爲最少知識原則(Least Knowledge Principle, LKP):一個對象應該對其餘對象有最少的瞭解。
朋友類:出如今成員變量、方法的輸入輸出參數中的類稱爲成員朋友類,而出如今方法內部的類不屬於朋友類。
類與類之間的關係是創建在類間的,而不是方法間,所以一個方法儘可能不要引入一個類中不存在的對象,固然JDK API提供的類除外。一個類公開的public屬性或方法越多,修改時涉及的面也就越大,變動引發的風險擴散也就越大。所以爲了保持朋友類間的距離,在設計時須要反覆衡量:是否還能夠再減小public屬性或方法,是否能夠加上final關鍵字等。迪米特法則要求,儘可能不要對外公佈太多的public方法和非靜態的public變量,儘可能內斂,多使用private、package-private(包類型,在類、方法、變量前不加訪問權限,則默認爲包類型)、protected等訪問權限。
迪米特法則的核心就是類間的解耦,弱耦合,只有弱耦合了之後,類的複用率才能夠提升。
6.開閉原則(Open Closed Principle):一個軟件實體如類、模塊和函數應該對擴展開放,對修改關閉。
前5個原則都是指導設計的工具和方法,是開閉原則的具體形態,而開閉原則纔是其精神領袖。
什麼是開閉原則:一個軟件實體應該經過擴展來其行爲來實現變化,而不是經過修改已有的代碼來實現變化。舉個例子吧,好比說想要在一個原有的接口基礎上,添加新的業務邏輯,那麼咱們不能去更改這個接口給它加一個新的方法,會影響到現有的實現類,這時候咱們就能夠新建一個類去繼承接口的某一個實現類,並重寫相關業務方法處理新的業務邏輯。
採用開閉原則的好處:
1.開閉原則對測試的影響:好比說咱們在系統中開發了一個新的功能,那咱們測試這個功能時須要從新寫一個測試這個功能的方法或類,而不是在原有其餘功能的測試方法或類上面修改。
2.開閉原則能夠提升複用性:在面向對象的設計中,全部的邏輯都是從原子邏輯組合而來的,而不是在一個類中獨立實現一個業務邏輯。只有這樣代碼才能夠複用,粒度越小,被複用的可能性就越大。
3.開閉原則能夠提升可維護性:當咱們維護代碼時,最樂意作的是擴展一個類,而不是修改一個類,關鍵是那還不是你本身寫的,想一想都很痛苦。
如何使用開閉原則:
1.對象約束:第一,經過接口或抽象類約束擴展,對擴展的邊界限定,不容許出如今接口或抽象類中不存在的public方法;第二,參數類型、引用對象儘可能使用接口或者抽象類,而不是實現類;第三,抽象層儘可能保持穩定,一旦肯定即不容許修改。
2.元數據控制模塊行爲:元數據就是用來描述環境和數據的數據,就比如咱們配置文件中配置的參數。我以爲使用最多的就是spring了,由於spring的配置文件真的不少(可是如今廣泛使用springboot了)。
3.制定項目章程:每一個公司都會有本身的代碼開發規範。
4.封裝變化:第一,將相同的變化封裝到一個接口或抽象類中;第二,將不一樣的變化封裝到不一樣的接口或抽象類中,不該該有兩個不一樣的變化出如今同一個接口或抽象類中。
綜上所述,原則只是提供參考,若是違背了這些原則,項目也未必會是失敗,這就須要你們在採用原則時反覆度量,不遵循是不對的,但也不要爲了套用原則而作項目。
可能理解不深入,望指正!!