簡述設(shè)計(jì)模式

本文用一句話簡述各種設(shè)計(jì)模式, 旨在給自己做個(gè)備忘. 如果我工作中有用到過的場景, 我也順帶提一嘴, 因?yàn)槠鋵?shí)你對(duì)代碼在進(jìn)行各種封裝, 分拆, 優(yōu)化等的時(shí)候, 你用的方法就是別人抽象出來的某種設(shè)計(jì)模式之一. 所以并不是先學(xué)設(shè)計(jì)模式才會(huì)架構(gòu)代碼.
比如, 以前我的老板總是要我把任何第三方庫都按他的要求包一層, 這樣輸出的接口風(fēng)格都是一樣的, 也是他最容易理解的. 老板在提這個(gè)要求的時(shí)候, 不會(huì)是因?yàn)?我要用界面模式來重構(gòu)", 而是真的就是要我封裝成更易理解的API.

  • 創(chuàng)建型: 這類模式提供創(chuàng)建對(duì)象的機(jī)制柒昏, 能夠提升已有代碼的靈活性和可復(fù)用性轻要。
  • 結(jié)構(gòu)型:這類模式介紹如何將對(duì)象和類組裝成較大的結(jié)構(gòu)蛤奥, 并同時(shí)保持結(jié)構(gòu)的靈活和高效软族。
  • 行為模式:這類模式負(fù)責(zé)對(duì)象間的高效溝通和職責(zé)委派藏澳。

設(shè)計(jì)模式 \begin{cases} 創(chuàng)建型 \begin{cases} 工廠(\tt Factory) \\ 生成器(\tt Builder) \\ 原型(\tt Prototype) \\ 單例(\tt Singleton) \end {cases} \\ \\ 結(jié)構(gòu)型 \begin{cases} 適配器(\tt Adapter) \\ 橋接(\tt Bridge) \\ 裝飾者(\tt Decorator) \\ 組合(\tt Composite) \\ 外觀(\tt Facade) \\ 享元(\tt Flyweight) \\ 代理(\tt Proxy) \end {cases} \\ \\ 行為模式 \begin{cases} 責(zé)任鏈(\tt Chain\ of\ Responsibility) \\ 命令(\tt Command) \\ 迭代器(\tt Iterator) \\ 中介者(\tt Mediator) \\ 備忘錄(\tt Memento) \\ 觀察者(\tt Observer) \\ 狀態(tài)(\tt State) \\ 策略(\tt Strategy) \\ 模板方法(\tt Template\ Method) \\ 訪問者(\tt Visitor) \\ 解釋器(\tt interpreter)? \\ \end {cases} \\ \end{cases}

創(chuàng)建型模式

工廠模式

用create代替new, 可以通過工廠方法來創(chuàng)建(同類不同性質(zhì)的)對(duì)象, 比如new Ship(), new Truck()CreateTranport(), 哪個(gè)擴(kuò)展性更高?

生成器(構(gòu)造者)

將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離, 使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示.

相比工廠模式創(chuàng)建船只還是卡車, 如果只是創(chuàng)建卡車, 要個(gè)性化, 一般靠一堆入?yún)? 生成器模式建議將對(duì)象構(gòu)造代碼從產(chǎn)品類中抽取出來婆誓, 并將其放在一個(gè)名為生成器的獨(dú)立對(duì)象中懈费。

  • create house
  • build walls
  • build doors
  • build windows
  • ...

原型模式

  • 用原型實(shí)例指定創(chuàng)建對(duì)象的種類, 并且通過拷貝這些原型創(chuàng)建新的對(duì)象.
  • 原型模式將克隆過程委派給被克隆的實(shí)際對(duì)象楔敌。 (即不由第三方來克隆一個(gè)對(duì)象)

單例模式

  • 保證一個(gè)類只有一個(gè)實(shí)例, 并且提供一個(gè)全局訪問點(diǎn).
  • 為什么會(huì)有人想要控制一個(gè)類所擁有的實(shí)例數(shù)量? 最常見的原因是控制某些共享資源 (例如數(shù)據(jù)庫或文件) 的訪問權(quán)限饲嗽。
  • 將默認(rèn)構(gòu)造函數(shù)設(shè)為私有炭玫, 防止其他對(duì)象使用單例類的 new運(yùn)算符。
  • 新建一個(gè)靜態(tài)構(gòu)建方法作為構(gòu)造函數(shù)貌虾。 該函數(shù)會(huì) “偷偷” 調(diào)用私有構(gòu)造函數(shù)來創(chuàng)建對(duì)象吞加, 并將其保存在一個(gè)靜態(tài)成員變量中。 此后所有對(duì)于該函數(shù)的調(diào)用都將返回這一緩存對(duì)象尽狠。

結(jié)構(gòu)型模式

適配器模式

將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另一個(gè)接口. 適配器模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作.

橋接模式

將抽象部分與它的實(shí)現(xiàn)部分分離. 沒看懂, 示例是用組合來代替繼承, 比如抽象成顏色和形狀兩個(gè)類, 這樣可以組成出來各種顏色的形狀

組合模式

將對(duì)象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu). 組合模式使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性.

示例, 一堆盒子里裝著不同的產(chǎn)品, 要計(jì)算總價(jià), 你可以遍歷, 也可以讓每個(gè)盒子負(fù)責(zé)自己的總價(jià), 這樣我們只要計(jì)算盒子的總價(jià), 而無需關(guān)心每個(gè)"部分"自己的實(shí)現(xiàn)

至少在這個(gè)例子中, 有個(gè)特性, 即自己是一種東西(訂單), 組合到一起也是一樣的東西(訂單), 雖然生產(chǎn)中都是組合在一起呈現(xiàn)的, 但自己也要實(shí)現(xiàn)組合后的類型的一些功能, 比如算總價(jià)

裝飾者模式

動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé).

  • 就增加功能來說, 裝飾者模式相比生成子類更為靈活.
  • 就實(shí)現(xiàn)來說, 由繼承一個(gè)類變成了"包裝"一個(gè)類, 其實(shí)就是把原來的功能包到一個(gè)新對(duì)象里去

外觀模式

為子系統(tǒng)中的一組接口提供一個(gè)一致的界面, 外觀定義了一個(gè)高層接口, 這個(gè)接口使得這一子系統(tǒng)更加容易使用.

一般我們把第三方組件包裝一些便捷方法, 也可以理解為外觀模式, 這樣調(diào)用者就不需要關(guān)心第三方組件的實(shí)現(xiàn)了, 類似適配器, 多了個(gè)中介

享元模式

通過共享多個(gè)對(duì)象所共有的相同狀態(tài)衔憨, 讓你能在有限的內(nèi)存容量中載入更多對(duì)象。

比如一個(gè)對(duì)戰(zhàn)游戲, 每一粒子彈是一個(gè)類實(shí)例, 有形狀位置貼圖等等數(shù)據(jù), 滿屏幕的子彈內(nèi)存就吃不消了, 通過觀察可以發(fā)現(xiàn)子彈的貼圖和形狀什么的都是一樣的, 只需要根據(jù)是子彈還是炮彈做個(gè)簡單區(qū)分, 沒必要把這么消耗的資源存到每一個(gè)實(shí)例里

代理模式

為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問. 為什么要控制對(duì)于某個(gè)對(duì)象的訪問呢袄膏? 舉個(gè)例子: 有這樣一個(gè)消耗大量系統(tǒng)資源的巨型對(duì)象(數(shù)據(jù)庫連接)践图, 你只是偶爾需要使用它, 并非總是需要沉馆。
解決: 在客戶端和數(shù)據(jù)庫間加個(gè)代理, 代理可處理延遲初始化和緩存查詢結(jié)果等工作

  • 信用卡是銀行賬戶的代理
  • 銀行賬戶是現(xiàn)金的代理

行為模式

責(zé)任鏈模式

感覺更像一個(gè)工作流, 比如登錄, 鑒權(quán), 過濾重復(fù)IP等等, 全部揉在一起和依次有序各做各的區(qū)別

命令模式

將一個(gè)請(qǐng)求封裝為一個(gè)對(duì)象, 從而可以用不同的請(qǐng)求對(duì)客戶進(jìn)行參數(shù)化;

其實(shí)封裝GUI的事件就是一個(gè)命令模式, 不同的GUI按鈕可以完成同一個(gè)任務(wù), 而不是為每一個(gè)功能子類化一個(gè)Button, 而且萬一要改變"復(fù)制"的行為, 還得跑到每一個(gè)子類里面去改

迭代器模式

提供一種方法來訪問一個(gè)聚合對(duì)象中的各個(gè)元素, 而又無須暴露該對(duì)象的內(nèi)部表示(列表, 棧, 樹等).

中介者模式

用一個(gè)中介對(duì)象來封裝一系列的對(duì)象交互. 中介者使各對(duì)象不需要顯式地相互引用, 從而使其耦合松散, 而且可以獨(dú)立地改變它們之間的交互.

把相互引用相互依賴改為中介引用所有人, 所有人只引用中介. 組件化和解耦常用

備忘錄模式

在不破壞封裝性的前提下, 捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài), 并在該對(duì)象之外保存這個(gè)狀態(tài). 這樣以后, 就可以在不破壞封裝性的前提下, 將該對(duì)象恢復(fù)到原先保存的狀態(tài). 比如設(shè)計(jì)文檔編輯器, 需要能追溯和回滾每一步的操作, 這些快照需要由文檔類來提供

觀察者模式

  • 允許你定義一種訂閱機(jī)制平项, 可在對(duì)象事件發(fā)生時(shí)通知多個(gè) “觀察” 該對(duì)象的其他對(duì)象赫舒。
  • 核心就是三件事: 訂閱, 發(fā)布, 和查話詢訂閱對(duì)象.
  • 次要的當(dāng)然還有解除訂閱等功能

狀態(tài)模式

  • 允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)改變時(shí)改變它的行為. 對(duì)象看起來似乎修改了它的類.
  • 比如一個(gè)文檔的不同狀態(tài)下, 對(duì)應(yīng)不同的方法, 而不是把這些方法實(shí)現(xiàn)在文檔類中
  • 比如手機(jī)在解鎖和未解鎖狀態(tài)下, 同一按鈕對(duì)應(yīng)不同的功能(而不是在里面不停地做if-else)

策略模式

  • 定義一系列算法, 將每一個(gè)算法封裝起來, 并使它們可以相互替換.
  • 等于入口類只需要set strategy, 和execute, 真正的執(zhí)行則由strategy來負(fù)責(zé)
  • 比如設(shè)計(jì)導(dǎo)航類, 你只需要關(guān)心起點(diǎn)終點(diǎn)和途徑點(diǎn), 以及設(shè)定是騎行還是導(dǎo)航, 真天上的路徑規(guī)劃在每個(gè)策略算法中

模板方法模式

  1. 定義一個(gè)操作中的算法的骨架, 而將一些步驟延遲到子類中. 模板方法使得子類可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟.
  2. 跟生成器把一個(gè)構(gòu)造變成N個(gè)構(gòu)建類似, 模板方法將一個(gè)流程變成N個(gè)step, 區(qū)別就在于build沒有先后, 而step則順序相關(guān)
  3. 比如解析文檔的類, 可以標(biāo)準(zhǔn)化為打開文檔, 解析文檔, 抽象出數(shù)據(jù)結(jié)構(gòu), 解析數(shù)據(jù), 生成報(bào)告等, 前幾步根據(jù)文檔類型都吧可以個(gè)性化, 因此可以交由子類自行實(shí)現(xiàn)
  4. 上述2和3說的不是一回事, 一個(gè)是自由組合step, 一個(gè)是從既定步驟里找到需要個(gè)性化的步驟把它抽象, 由子類延遲實(shí)現(xiàn)

訪問者模式

它能將算法與其所作用的對(duì)象隔離開來。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末闽瓢,一起剝皮案震驚了整個(gè)濱河市接癌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌扣讼,老刑警劉巖缺猛,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異椭符,居然都是意外死亡荔燎,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門销钝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來有咨,“玉大人,你說我怎么就攤上這事蒸健∽恚” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵似忧,是天一觀的道長渣叛。 經(jīng)常有香客問我,道長盯捌,這世上最難降的妖魔是什么淳衙? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮饺著,結(jié)果婚禮上箫攀,老公的妹妹穿的比我還像新娘。我一直安慰自己幼衰,他們只是感情好靴跛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著塑顺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪俏险。 梳的紋絲不亂的頭發(fā)上严拒,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音竖独,去河邊找鬼裤唠。 笑死,一個(gè)胖子當(dāng)著我的面吹牛莹痢,可吹牛的內(nèi)容都是我干的种蘸。 我是一名探鬼主播墓赴,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼航瞭!你這毒婦竟也來了诫硕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤刊侯,失蹤者是張志新(化名)和其女友劉穎章办,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體滨彻,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡藕届,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了亭饵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片休偶。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖辜羊,靈堂內(nèi)的尸體忽然破棺而出踏兜,到底是詐尸還是另有隱情,我是刑警寧澤只冻,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布庇麦,位于F島的核電站,受9級(jí)特大地震影響喜德,放射性物質(zhì)發(fā)生泄漏山橄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一舍悯、第九天 我趴在偏房一處隱蔽的房頂上張望航棱。 院中可真熱鬧,春花似錦萌衬、人聲如沸饮醇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽朴艰。三九已至,卻和暖如春混移,著一層夾襖步出監(jiān)牢的瞬間祠墅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來泰國打工歌径, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留毁嗦,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓回铛,卻偏偏與公主長得像狗准,于是被迫代替她去往敵國和親克锣。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容