設計模式學習筆記

設計模式學習筆記

前言

以前去面試迅雷實習生,被問到設計模式相關的問題,居然一時語塞,腦海裏只有「工廠模式」、「簡單工廠模式」之類的概念,卻不能用清晰的語言表述出來。在面試的間隙看了一眼相關的資料,發現不少設計模式在平常的學習中已經用到過,但並無系統的整理學習過————因而如今有了這篇博客。javascript

參考資料:html

  1. 《松本行弘的程序世界》第四章 設計模式
  2. AlloyTeam的博客
  3. Design Pattern - Read the Docs

由於意識不到應該使用的模式,就會錯過最合適的設計。——《松本行弘的程序世界》java

什麼是模式?

一般,建築物的設計各不相同,另外加上用途、建築條件等各類制約因素,一個設計是不能一成不變地套用到別的建築物上的。建築設計師只是經過重用積累的設計模式,試圖縮短設計所花費的時間。程序員

在軟件設計中,最多見的重用方式是使用庫。各類軟件經過庫共享處理過程、數據結構以及類等。面試

可是,只有庫還不能達到充分的共享。軟件設計中有些東西雖然不能以庫的形式來把它獨立出來,可是多個軟件共通利用的東西是確實存在的。這樣的東西只能稱之爲固定形式——模式算法

一種最簡單的模式:設計模式

for (let i = 0; i < len; i++) {
    ...
}

在軟件設計中像這樣的模式數不勝數。不過,設計人員本身不多可以意識到模式的存在,通常是在積累了不少經驗以後,才幾乎在無心識之中利用模式提升了軟件開發的效率。數據結構

Erich Gamma 與幾位合做者一塊兒,精選了軟件設計中,特別是面向對象軟件設計中反覆出現的各類模式,比照着 Alexander 提倡的建築上的概念,稱之爲「設計模式」。他們從本身及周圍的開發經驗中把模式總結出來並進行分類,出版了《設計模式》一書。框架

Erich Gamma 總結的 23 種設計模式學習

模式名 內容
Abstract Factory(抽象工廠) 用可配置的方法生成有關的對象羣
Adapter(適配器) 變換對象的接口
Bridge(橋接) 分離類之間的實現
Builder(生成器) 分離複雜對象的生成過程
Chain of Responsibility(職責鏈) 用多個對象來處理請求
Command(命令) 把請求封裝成對象
Composite(組合) 用樹結構來構成對象
Decorator(裝飾) 給對象動態增長新的功能
Facade(外觀) 隱藏子系統的詳細內容,提供統一的接口
Factory Method(工廠方法) 在父類只定義生成對象的接口,具體的生成過程由派生類來實現
Flyweight(享元) 以共享的方式提升大量小對象的實現效率
Interpreter(解釋器) 語言解釋器
Iterator(迭代器) 提供按順序訪問一組對象的方法
Mediator(中介者) 封裝對象之間的相互做用
Memento(備忘錄) 記錄對象的內部狀態
Observer(觀察者) 把對象的狀態變動通知給其餘對象
Prototype(原型) 提供生成對象的原型
Proxy(代理) 提供控制對象訪問的代理(容器)
Singleton(單件) 用來保證某個類的實例只有一個
State(狀態) 把對象的內部狀態獨立出來,封裝狀態變化
Strategy(策略) 封裝算法,使之具備可變換性
Template Method(模板方法) 父類定義框架,派生類具體實現其中一部分
Visitor(訪問者) 對集合的元素進行操做

設計模式的意義和價值

引用自《松本行弘的程序世界》:

首先,它明確了各類模式的效果和適用情況,給衆多模式命名並進行分類,這自己就是很是有意義的。若是沒有名字的話,即便使用了模式,程序員也大都沒有明確意識到使用了模式。由於意識不到應該使用的模式,就會錯過最合適的設計。

可是,他們最大的功績並不在於把設計模式進行分類,而是明確了「軟件中能夠分類的設計模式」的存在。有了這樣的認識以後,設計模式就不只限於書中介紹的23個,人們開始發現和定義更多設計模式。

設計模式有了名字,人們就能夠認識到它的存在。對於沒有名字的東西,人們幾乎不可能認識到它的存在,並對之進行討論。這種不能用語言表達的知識咱們稱之爲內隱知識。給這些在軟件中常常反覆出現的模式命名,使得這些原本只有經驗豐富的程序員才能認識到的軟件設計模式能被普遍認識和討論。這樣的知識稱爲形式知識。把迄今爲止普通人難於學習和吸取的內隱知識變成形式知識的功績是無與倫比的。

簡單工廠模式 & 工廠方法模式 & 抽象工廠模式

  • 簡單工廠模式:
    • 經過傳遞參數,判斷參數的值來返回不一樣類的實例。
    • 優勢:使用方便,只需傳入參數便可。
    • 缺點:邏輯集中,出現問題整個系統受影響;難以擴展,擴展須要修改判斷的邏輯,不符合開閉原則。
    • 適用於工廠類負責建立的對象較少的狀況。
    function buttonFactory (String type) {
     if (type == "RedButton") {
         ...
         return new RedButton();
     } else if (type == "BlueButton") {
         ...
         return new BlueButton();
     }
    }
  • 工廠方法模式:
    • 父類提供公共接口,子類負責生產具體對象。
    • 優勢:無需關心產品,只需關心對應的工廠;可擴展性好,加入新產品只需添加具體工廠和具體產品,無需修改其餘,符合開閉原則。
    • 缺點:類的數量增長(每一個產品都要提供對應的工廠類),增長了抽象性和複雜度。
    class ButtonFactory {
     onClick() {
         ...
     }
    }
    class RedButtonFactory extends ButtonFactory {
     constructor: () => { 
         ... 
         retrun RedButton;
     }
    }
    class BlueButtonFactory extends ButtonFactory {
     ...
     constructor: () => {
         ...
         return BlueButton;
     }
    }
  • 抽象工廠模式:
    • 在工廠方法模式的基礎上,一個工廠能夠提供多個產品對象。
    • 由此衍生出了產品等級結構(繼承結構)產品族(不一樣等級結構中的一組產品)
    • 優勢:擴展方便,無須修改已有系統,符合開閉原則;高內聚低耦合;當一個產品族中的多個對象被設計成一塊兒工做時,可以保證客戶端始終只使用同一個產品族中的對象。
    • 缺點:加新的工廠和產品族容易,增長新的產品等級結構麻煩。
    class Theme {
     CreateButton();
     CreateBackground();
     CreateNav();
    }
    class RedTheme {
     CreateButton() {
         return RedButton;
     }
     CreateBackground() {
         return RedBackground;
     }
     CreateNav() {
         return RedNav;
     }
    }
    class BlueTheme {
     CreateButton() {
         return BlueButton;
     }
     CreateBackground() {
         return BlueBackground;
     }
     CreateNav() {
         return BlueNav;
     }
    }

工廠模式的退化

  • 當抽象工廠模式中每個具體工廠類只建立一個產品對象,也就是隻存在一個產品等級結構時,抽象工廠模式退化成工廠方法模式;
  • 當工廠方法模式中抽象工廠與具體工廠合併,提供一個統一的工廠來建立產品對象,並將建立對象的工廠方法設計爲靜態方法時,工廠方法模式退化成簡單工廠模式。

持續更新中...

單例模式

相關文章
相關標籤/搜索