一直想整理一下23種設計模式,因而給本身定了一個一天一模式的任務,工做之餘用一天時間整理一種模式。算法
這麼作的緣由是:編程
至少在我工做和學習的過程當中,在需求變動時、閱讀源碼時、修改BUG時,設計模式幫助了我不少。設計模式
在記錄的過程當中,雖然對每種模式都進行了分析,而後嘗試給出反例,再用設計模式優化這個反例達到預期的效果,但缺乏了從總體上去理解設計模式的一些說明。因此,在記錄完成後寫一個總結,也算善始善終,對本身負責。緩存
下面就說說現階段的我,是怎麼理解設計模式的。安全
- 若是你想要你的項目擴展性更強,請使用設計模式。
- 若是你想要你的程序複用率更高,請使用設計模式。
- 若是你想要你的代碼可讀性更好,請使用設計模式。
設計模式(Design Pattern)是前輩們對代碼開發經驗的總結,是解決特定問題的一系列套路。它不是語法規定,而是一套用來提升代碼可複用性、可維護性、可讀性、穩健性以及安全性的解決方案。網絡
軟件的設計模式來自於1995 年,GoF(Gang of Four,四人組/四人Bang)合做出版了《設計模式:可複用面向對象軟件的基礎》一書,共收錄了 23 種設計模式,今後樹立了軟件設計模式領域的里程碑,人稱「GoF設計模式」。數據結構
我認爲設計模式最大的價值在於,能夠擁抱需求變動,讓程序具有快速開發,快速測試的能力。併發
例如建築工程,建造一座橋,不會建到一半的時候甲方提出橋的長度要在加200米這種離譜的要求。而軟件工程不同,在軟件開發錢,開發中,開發後,都會有需求變動。因此要經過對一些特定的場景使用合適的設計模式擁抱需求變動。框架
下面總結一下爲何要使用設計模式的幾個點,現階段技術水平的我能想到的好處以下:高併發
對上面三點,用一句話總結就是,設計模式的本質是面向對象設計原則的實際運用,是對類的封裝性、繼承性和多態性,以及類的關聯關係和組合關係的充分理解,最終讓程序具有高內聚與低耦合這兩個特性。
高內聚是指將相關的行爲彙集在一塊兒,把不相關的行爲放在別處。由於若是要改變某個行爲時,最好可以只在一個地方修改,而後就能夠儘快的測試和發佈。
低耦合是指將盡量少的讓實現業務的一些服務或模塊有很深度的交互,若是能夠作到,那麼會減小在修改某些功能時出現按下葫蘆起來瓢的狀況。
其實一個好的軟件設計就是在追求高內聚與低耦合,而後作到快速完成需求變動,快速完成測試,快速發佈上線。
爲了作到這一點,軟件設計的大師們總結出了6個設計原則,正是基於這6個設計原則,對實際開發過程當中出現頻率很高23個場景,提供了23種設計模式,下面來講說這6個原則。
23種設計模式都是在幫助系統具有開閉原則。
網上對這六個原則的介紹已經有不少了,在這裏就不一一介紹了。
主要就說說開閉原則,開閉原則的定義是:
對新增開放,對修改關閉。
就是說在設計時,對有可能從此發生需求變動的地方作好預留,保證當需求變動發生時,不修改已經開發過的代碼部分,以新開發代碼的方式來完成此次需求變動。
舉個例子,系統要求有基於用戶名和密碼登陸系統的功能,設計人員在設計這個需求時,應該考慮,有可能有一天客戶會要求系統加入經過用戶名和短信驗證碼登陸的功能。那麼對登陸模塊須要稍微設計一下,當需求變動時,不須要修改已經開發完成的用戶名密碼登陸的代碼,就能夠加入新功能。
上圖中,前5個設計原則的定義就是爲了引出開閉原則,簡單理解就是具有了前5個設計原則,就等於具有了開閉原則。
下面就開始說說設計模式。
設計模式能夠分爲三大類:
下面是我整理的23種設計模式的表格,儘量以一句通俗易懂的話來講明何時可使用該模式(這很困難),而後提供每種模式的我整理的記錄的鏈接,但願對你們有所幫助。
序號 | 分類 | 名稱 | 使用場景 | 備註 |
1 | 建立型 | 單例模式 | 對象在程序的生命週期內只存在一份時,可使用單例模式。 | 有5種單例的實現方式。 |
2 | 工廠模式 | 建立對象時,不一樣場景下建立的對象不一樣,可使用工廠模式。 | 父類定義通用部分,子類實現不一樣部分 | |
3 | 抽象工廠模式 | 建立一族對象,且對象的類別維度大於1時,可使用抽象工廠模式。 | 一個維度是工廠數量,另外一個是工廠內方法的數量。 | |
4 | 建造者模式 | 分步建立一個對象,且步驟順序要求可變化時,可使用建造者模式。 | 經過鏈式表達式建立對象。 | |
5 | 原型模式 | 把一個對象做爲模板來建立新對象且有性能要求時,可使用原型模式。 | 使用Java的clone方法。 | |
6 | 結構型 | 適配器模式 | 把一個接口轉化成另外一個接口,達到本來不能在一塊兒工做的兩個對象變的能夠一塊兒工做(適配),可使用適配器模式。 | 想象變壓器的使用場景。 |
7 | 橋接模式 | 當類的功能層次結構與實現層級結構混雜在一個層級結構中,爲了便於後續擴展,可使用橋接模式。 | 橋接模式使用場景很少,但能夠幫助很好的理解面相對象。 | |
8 | 組合模式 | 將不一樣的對象組合成樹狀結構,且要求某些場景下各個層級的節點無差異時,可使用組合模式。 | 常見的有多級結構均可以考慮組合模式。 | |
9 | 裝飾者模式 | 要在不改變對象的狀況下,動態的給對象附加功能,可使用裝飾者模式。 | 想象Java的InputStream結構。 | |
10 | 門面模式 | 一個功能須要不少對象協同工做完成,能夠把協同工做的過程封裝到一個新對象種,讓調用者不須要知道不少細節,這時可使用門面模式 | 講複雜業務作類提煉。 | |
11 | 享元模式 | 把不變的外部資源加載到緩存池中,加載後就只從緩存池中讀取,這時可使用享元模式。 | 理解爲緩存中有從緩存中取,沒有則從文件系統或網絡上加載。 | |
12 | 代理模式 | Client調用某對象時,在調用前,調用後添加額外業務,但不想修改被調對象,這時可使用代理模式。 | 代理模式有靜態代理,JDK動態代理和Cglib。 | |
13 | 行爲型 | 責任鏈模式 | 某項業務須要通過一系列審批(驗證),且要求審批過程可變化,這時可使用責任鏈模式。 | 能夠設置責任鏈環節的順序,隨時可實現新驗證環節。 |
14 | 命令模式 | 業務相似一些命令動做,切須要可撤回命令,同時想解除發號施令者與執行命令者之間的耦合,這時可使用命令模式。 | Client建立命令對象,而後指派某個對象去完成命令,不須要調用指派對象的方法(低耦合)。 | |
15 | 迭代器模式 | 不想把對象內部的可遍歷的數據結構暴露給Client,但還須要Client能夠遍歷這個數據結構,這時可使用迭代器模式。 | Java中好多方法都使用Iterator。 | |
16 | 中介者模式 | 當爲了完成某個業務時,發現不少對象的調用關係成網狀了,這時可使用中介者模式下降耦合度。 | 這些對象只跟中介者有耦合。 | |
17 | 備忘錄模式 | 要爲對象記錄一個快照,且可經過快照覆蓋對象時,可使用備忘錄模式。 |
將對象保存到一個新對象中,在必要時覆蓋回來。快照不可修改。 |
|
18 | 觀察者模式 | 當某個對象狀態發生變化時,要批量通知多個對象,這時可使用觀察者模式。 | Java有內置觀察者模式,可是須要使用繼承的方式去實現,更推薦本身實現 |
|
19 | 狀態模式 | 對象的行爲,在不一樣狀態時有不一樣實現,這時可使用狀態模式。 | 將狀態用類表示,經過狀態建立類,調用方法 | |
20 | 策略模式 | 對象的某些業務算法,在不一樣場景下有不一樣實現,這時可使用策略模式。 | 算法不一樣時使用策略模式,作法與狀態模式差很少,是場景上的區別。 | |
21 | 模板方法模式 | 對象的業務算法流程相同,但在不一樣場景,某些步驟不一樣,這時可使用模板方法模式。 | 父類中實現通用的步驟,將不一樣的步驟定義成抽象方法,等着子類去實現。 | |
22 | 訪問者模式 | 將對象中操做其數據結構的方法拆分出來,可使用訪問者模式。 | 操做數據結構的方法太多,使用該模式提升可讀性。 | |
23 | 解釋器模式 | 相對某種語法進行解析,但是使用解釋器模式。 | 使用場景很少。 |
設計模式的優勢有不少,講解這方面知識的書也有不少,只要是稍有一些面向對象編程經驗的同窗都能看懂。
推薦幾本我看過的書《Head First設計模式》、《圖解設計模式》、《設計模式之禪》,《大話設計模式》這些書都很淺顯易懂。
另外除了設計模式,還有不少書籍也講解了能夠提升代碼的擴展性,重用性和可讀性的方法,例如《重構》,《代碼整潔之道》,《領域驅動設計》等等。
學習這些的目的是爲了寫出高質量的代碼,維護時出錯概率小,交接時可讀性強。
在同窗們天天都學習處理高併發,海量數據之餘,提高下本身的代碼質量也是不錯的選擇,就當是換換腦子。
另外打開那些經常使用框架(例如Spring,MyBatis等等)和中間件(例如Eureka,Ribbon等等),會發現他們的代碼編寫的很是優雅,也用到了不少設計模式。
因此學習學習設計模式對閱讀源碼還頗有幫助,另外,說不定某天本身作開源項目時,就用獲得了。
從自學編程開始就時不時看看設計模式,但一直沒有系統的記錄和整理,這篇博客做爲這段時間筆記的一個總結和一個傳送門,善始善終。
以上就結束了23種設計模式的整理,同時也準備下一輪的知識整理,目標還沒選好,先給本身點份炸雞不過度吧,哈哈。