在工做初期就看了關於設計模式的書《大話設計模式》簡單易懂,可是後來對一些設計模式漸漸模糊,記得最多或者你們說的最多的像單例、工廠記憶深入,如今回頭再看一遍,別以一番風味,理解又有不一樣,這裏我的簡單進行記錄,其中間雜着我的的一些看法。java
關於例子,你們能夠去找這邊本看看,或者直接到git上clone一下,地址:https://github.com/PengfeiLiOnGit/designpatterngit
設計模式除了23種外,確定還有衍生出來新的設計模式,可是萬武歸宗,實則都是對類的抽象。github
面向對象設計模式體現的就是抽象的思想,類是對對象的抽象,抽象類是對類的抽象,接口是對行爲的抽象。正則表達式
1、UML 類圖:算法
2、原則數據庫
單一職責原則:就一個類而言,應該僅有一個引發它變化的緣由。若是一個類承擔的職責過多,就等於把這些職責耦合在一塊兒,一個職責的變化可能會削弱或者抑制這個類完成其餘職責的能力。這種耦合會致使脆弱的設計,當變化發生時,設計會遭受到意想不到的破壞。編程
開放-封閉:軟件實體(類、模塊、函數)應該是能夠擴展,可是不能夠修改。面對需求,對程序的改動是經過新代碼進行的,而不是更改現有代碼。設計模式
依賴倒轉原則:抽象不該該依賴細節,細節應該依賴與抽象。(針對接口編程,不要對實現編程)。多線程
高層模塊依賴底層模塊-這是對的,可是若是是針對實現變成,好比數據庫訪問依賴某個數據操做,若是一旦更改數據庫,意味着高層數據庫訪問也須要改動,若是把高層和底層都進行抽象化,針對接口變成,那麼若是要更改西其餘數據庫,只須要針對底層訪問接口增長新實現就能夠,不要改動原有的代碼。函數
里氏代換原則:一個軟件實體若是使用的是一個父類的話,那麼必定適用與其子類,並且它察覺不出父類對象和子類對象的區別。也就是說,在軟件裏面,把父類都替換成它的子類,程序行爲沒有變化,簡單的說,子類型必須可以替換掉它們的父類型。
迪米特法則:若是兩個類沒必要彼此直接通訊,那麼這兩個類就不該當發生直接的相互做用。若是其中一個類須要調用另外一個類的某一個方法的話,可使用第三者轉發這個調用。(最少知識原則)
合成/聚合複用原則:儘可能使用合成/聚合,儘可能不要使用類繼承。聚合表示弱的「擁有關係」,體現的是A對象能夠包涵B對象,但B對象不是A對象的一部分;合成則是一種強的「擁有」關係,體現了嚴格的部分與總體的關係,同時部分和總體的生命週期同樣。
3、設計模式
一、簡單工廠:
針對不一樣相同的行爲可是不一樣的算法進行抽象,利用一個簡單工廠獲取實際的運算類。
二、策略:針對不一樣的算法進行封裝、讓它們之間能夠相互替換,此模式讓算法的變化不會影響到使用算法的用戶。
關鍵點在於context 經過聚合抽象策略類的引用,請求者只須要知道context的存在就能夠了,具體的配置再context進行判斷,想比較簡單工廠,耦合度再次下降。
固然在context中一樣能夠再次套用其餘模式避免switch分支,好比狀態模式等再次進行解耦,或者經過反射。
三、裝飾模式:動態的給一個對象添加一些額外的職責,就增長功能來講,裝飾模式比生成子類更加靈活。
關鍵點在於針對具體的對象,衍生於抽象裝飾類,其類繼承統一的抽象接口,而且在裝飾的實現類中對接口進行實現。在實際調用過程當中,針對實際對象進行調用統一的裝飾接口。
而且在抽象裝飾類中須要對對象接口進行引用,從而達到裝飾,也就添加邏輯的效果。
實際場景中在對某些現有功能須要增長業務的或者功能的時候,增長新的功能實現便可,而不須要修改原有抽象實現,去除原有方法中過多的職責。
四、代理模式:爲其餘對象提供一種代理以控制對這個對象的訪問。
關鍵點實際對象與代理同時實現相同的接口,同時代理對象保持對實際對象引用。
在實際環境中實際對象中可能會有不少私有邏輯,而請求者只知道代理而不知道實際對象。
五、工廠方法:定義一個用於建立對象的接口,讓子類決定實例化哪個類。工廠方法使一個類的實例化延遲到其子類。
相比較簡單工廠,工廠模式針對工廠進行抽象,消除了判斷與條件分支,若須要擴展實際產品,至須要實現product和creator,而不要修改原有工廠類代碼。
六、原型模式:
實際java使用中經過實現cloneAble接口,進行對象的拷貝工做。注意點在於,在實現過程當中須要注意淺拷貝與深拷貝的問題。
七、模版方法模式:模版方法在實際使用過程當中常用,也就是繼承的特色決定的。抽象類實現---- 子類重寫
八、外觀模式:爲子系統中的一組接口提供一個一致的界面,此模式定義了一個高層接口,這個接口使得這一子系統更多容易使用。
關鍵點自在於高層的外觀類引用具體的關聯對象,實現子系統的功能,並處理具體的任務。
實際場景中組合多個接口,同一在外觀類中進行業務處理,最終開放給外部調用者。有點相似於adapter 適配器,可是適配器的思想是針對某個負責的接口同一爲一個新的接口,適配器同時是擁有兄弟關係的。
九、建造者模式:將一個複雜的對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示。
關鍵點在於director對象,具體對象構造由它進行實現,雖然經過工廠模式也可實現,經過director 會顯示更大的靈活性,在指揮者對象中須要具備build的引用。
實際應用場景,建造抽象過程相同,可是具體的建造細節略有不一樣,便可以使用這種設計模式。
十、觀察者模式:發佈-訂閱模式,定義一種一對多的依賴關係,讓多個觀察者對象同時監聽一個主題對象。這個主題對象在狀態發生變化的時,會通知全部觀察者對象,使它們可以自動更新本身。
十一、抽象工廠模式:提供一個建立一系列相關或相互依賴對象的接口,而無需指定它們具體的類。
基於工廠模式再次對工廠進行抽象,實現的工廠與實現的生產對象再進行對應。抽象工廠比較臃腫,雖然實現瞭解耦,可是若是須要進行擴展,工做量也會很是之大,相比之下,利用泛型與反射,也已更加簡便的實現。
十二、狀態模式:當一個對象的內在狀態改變時容許改變其行爲,這個對象看起來像是改變了其類。
關鍵點在於context 是state的聚合引用,在實例調用handle處理的時候對state進行判斷,並更新context,並更改處理方式。
例如初始化狀態爲A,A的處理方式若是不知足就設置context中引用的狀態爲B或C等,根據不一樣的狀態從而使改變實現的方式,對於須要大量條件判斷的狀況下尤其適用。
1三、適配器模式:將一個類的接口轉換成客戶端但願的另一個接口。解決接口不兼容的問題。
在外觀模式中提到,對於已經存在的接口不兼容的狀況下進行使用,經過adapter類對原有的接口進行轉換。
實際場景,好比使用了第三方的接口,或者其餘同事或者原有接口,因爲其實現因爲各類緣由不能進行修改,因此使用適配器模式,則不須要關注具體實現。
1四、備忘錄模式:在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象以外保存這個狀態。這樣之後就可將該對象回覆到原先保存的狀態。
做爲備忘錄的彙集,實際保留備忘錄的引用,爲何要存在memento而不使用發起者的原型複製,緣由在於再實際過程當中不必定要保存全部信息,可能只是保留一個狀態,因此經過memento 實際存儲這些信息,
而經過彙集的引用在caretaker中,在須要恢復的時候從其中獲取便可。
1五、組合模式:將對象組合成樹形結構以標識‘部分-總體’的層次接口。組合模式使得用戶對單個對象和組合對象的使用具備一致性。
分支節點與葉子節點同事實現component接口,同時分支節點須要具備對對象接口的彙集引用。
1六、迭代器模式:提供一種方法順序的訪問一個聚合對象中的各個元素,而又不暴露該對象的內部表示。
迭代器在實際應用中須要的很少,由於你們面嚮對象語言中都已經實現了迭代器,迭代器中須要具備下標,與next方法來獲取對象,同時根據isDone 來判斷是否已經結束。
1七、單例模式:保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。
通常單例對象使用懶加載和DSL 雙鎖機制,來避免在多線程中生成多個對象。
若是使用飢渴模式的話無需考慮。
public static Singleton getInstance(){ // 在多線程訪問的狀況下利用DSL 雙重鎖機制保證明例惟一 // 由於是靜態方法,因此使用類鎖,或者使用lock 鎖,與生成一個對象鎖 if(singleton == null){ // 處理業務邏輯 // DSL synchronized (object){ if(singleton==null){ singleton = new Singleton(); } } } return singleton; }
1八、橋接模式:將抽象部分與它的實現部分分離,使它們均可以獨立的變化。
實現系統可能有多角度分析,每一種分類都有可能變化,那麼就把這種多角度分離出來讓它們獨立變化,減小它們之間的耦合。
好比手機能夠安裝品牌區分,同事每一個品牌手機中又擁有類似的功能,可是具體的功能在不一樣品牌中實現不一樣,那麼就可使用橋接模式進行體現。
手機品牌的抽象中聚合手機軟件、功能的引用。
利用聚合/複用原則進行弱引用,這樣增長品牌或者增長手機功能都不需對原有的代碼進行修改,直接擴展便可。
1九、命令模式:將一個請求封裝爲一個對象,從而使你可用不一樣的請求對客戶進行參數化,對請求排隊或記錄請求日誌,以及支持可撤銷的操做。
把命令進行抽象,命令的記錄與撤銷記錄在Receiver接收者中,同事在命令中具備最終調用者的引用,下面是書中的截圖引用。
20、職責鏈模式:使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關係。將這個對象練成一條鏈,並沿着這條鏈傳遞該請求,知道又一個對象處理它爲止。
關鍵點在於在實現類中須要具備父類的引用,在實現處理請求的時候若是不知足條件,則重置處理實現。
2一、中介模式:用一箇中介對象來封裝一系列的對象交互。中介者使各對象不須要顯示的相互引用,從而使其耦合鬆散,並且能夠獨立的改變它們之間的交互。
兩個對象進行交互同時經過中介者進行處理,多個對象只與中介對象進行通訊,具體的通訊由中介對象進行處理。
2二、享元模式:運用共享技術有效的支持大量細粒度的對象。
特色對於某一類對象經過共享實例的方式避免內存的過分濫用,同時與單例模式結合,針對須要重複引用的對象共享他們。
建立實例的事物能夠交給子類,而後由享元工廠提供接口進行分法。
2三、解釋器模式:給定一個語言,定義它的文法的一種表示,並定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。
實際使用場景很少,是一種轉換模式,比較出名的例子是正則表達式。
2四、訪問者模式:表示一個做用與某對象接口中的各元素的操做。它使你能夠在不改變各元素的類的前提下定義做用與這些元素的新操做。
針對特定的對象,進行抽象分類,同時在擴展狀態的時候能夠很是容易的進行擴展,可是若是要條件ele對象則會形成大量的工做。
此模式針對特定且固定分類的對象比較適用。
例如,男人和女人,可是會有不少中的狀態,就比較適合這種設計模式。