天天看點

[設計模式][GOF] 24種設計模式概述

網站推薦:

​​https://refactoringguru.cn/design-patterns/creational-patterns​​

簡單工廠:

簡單工廠就是根據入參的類型進行判斷需要建立那種對象,隻不過傳回值是一個基類指針,以此來完成傳回值類型的統一。

抽象工廠(Abstract Factory):

一系列接口,用于建立一系列相關或互相依賴的類。

[設計模式][GOF] 24種設計模式概述

工廠方法(Factory Method):

定義一個建立對象的接口,讓子類決定将哪個類執行個體化。比如,定義一個工廠基類,這個基類包含一個建立對象的接口,所有工廠都要繼承這個基類并實作接口。抽象工廠的核心理念是定義工廠基類,然後派生不同的工廠。

[設計模式][GOF] 24種設計模式概述
這三種工廠模式的差別:​​https://www.zhihu.com/question/20367734​​

擴充卡(Adapter):

對已有類的對外成員函數進行二次包裝,友善其他類使用,目的在于 已有類 和 其他類都不需要變動,這其實就相當于做一個接口上的互相相容。使用場景主要就是有些陳舊而複雜的兩個子產品,如果不希望通過修改代碼來完成子產品的相容,那麼就可以增加一個Adapter,這樣接口提供者不需要修改接口,接口使用者也不需要修改自己的業務代碼。

[設計模式][GOF] 24種設計模式概述

或者

[設計模式][GOF] 24種設計模式概述

橋(Bridge):

将抽象部分和實作部分分離,是他們都能獨立地變化,比如如果多個類都有相似或同樣的成員函數,那麼可以把這些函數都歸納為一個接口類,然後讓那些類都繼承這個接口類。

[設計模式][GOF] 24種設計模式概述

初始化代理(Builder):

如果某個對象的建立特别複雜,那麼可以把建立過程內建到一個Builder類中。

[設計模式][GOF] 24種設計模式概述

責任鍊(Chain of Responsibility):

将事件封裝成一個類,然後把事件傳遞給一系列有繼承層級關系的類執行個體連結清單中,這些類都有着統一的虛函數接口,這個接口接收事件類作為參數,由連結清單中的每個節點自行決定是否處理這個事件。可以對比Qt中的 Event系統,每個對象都有自己的 Event Handler函數,并在這些函數中決定是否處理Event,甚至可以決定是否截獲或者繼續向下傳遞。

[設計模式][GOF] 24種設計模式概述
class Event {
//...
public:
  char i;
//...
};

class A{
//...

public:
  virtual bool isMyEvent(Event* e) {
    if (e->i = 'A') return true;
    else return false;
  }
  virtual void eventHandler(Event* e) {
    if (isMyEvent(e)) {
      doWorkofA(e);
    }
    else {
      //誰都不要的Event
    }
  }

  void doWorkofA(Event* e) {
    //做點啥
  }

//...

};

class B :public A {
  //...

public:
  virtual bool isMyEvent(Event* e) {
    if (e->i = 'B') return true;
    else return false;
  }
  virtual void eventHandler(Event* e) {
    if (isMyEvent(e)) {
      doWorkofB(e);
    }
    else {
      A::eventHandler(e);   //傳給父類處理
    }
  }

  void doWorkofB(Event* e) {
    //做點啥
  }

  //...
};

class C :public B {
  //...

  virtual bool isMyEvent(Event* e) {
    if (e->i = 'C') return true;
    else return false;
  }
  virtual void eventHandler(Event* e) {
    if (isMyEvent(e)) {
      doWorkofC(e);
    }
    else {
      A::eventHandler(e);   //這裡可以選擇随意傳給誰處理
    }
  }

  void doWorkofC(Event* e) {
    //做點啥
  }

  //...
};      
注:責任鍊模式有幾個要點:1)最頂層的基類要進行事件兜底;2)如果事件不歸自己處理那麼要通過  父類名::虛函數 的方式把事件交給父類的虛函數處理;3)因為是代碼控制流程,是以鍊條可以分叉/截斷/跳級傳送等等,這就要在代碼的判斷虛函數中人為控制。

指令(Command):

将請求封裝成類,這些類都繼承自同一個基類,每個類都實作基類的虛函數,這個虛函數内是屬于目前Command的業務代碼,然後讓其他類可以接收和使用這個對象。還是對比Qt的Evenet系統,所有的事件都繼承自QEvent ,這個設計模式在日常代碼中經常使用,隻是很多時候我們都沒發現而已。為了友善記憶,我們可以類比Linux的指令行,每個指令都繼承自一個指令類,然後各自實作自己的業務,這些指令都會被 bash 接受和執行内部的虛函數,bash隻需要調用對應的虛函數即可。

[設計模式][GOF] 24種設計模式概述

組合(Composite):

将對象組合成樹形結構,這種設計模式主要用來讓客戶對單個對象和符合對象使用具有一緻性。

[設計模式][GOF] 24種設計模式概述
[設計模式][GOF] 24種設計模式概述
注:組合模式的核心就是嵌套,實作抽象類的具體類内部又包含N個抽象類,具體類内部提供周遊自身的操作,這樣就可以保證了一個樹形結構,每個節點都可以調用周遊接口來繪制自己的所有子節點。這種模式不是很特别,是以我們即便用到了可能也不知情。

修飾者(Decorator):

動态地給一個對象添加一些額外的職責或功能。這種方式比生成子類更加靈活。注意這裡是給對象添加額外内容,這有别于繼承某個接口而實作某個功能,繼承是針對類的,這裡是針對對象的。我們可以在Qt中找到相應的應用和實作,那就是Qt的動态屬性功能,Qt可以給已經建立的執行個體添加動态屬性以友善功能擴充。

[設計模式][GOF] 24種設計模式概述
注:圖中Decorator的component成員就是那個需要被修飾的對象

面(Facade):

為子系統的一組接口提供一個一直的界面,主要是為了讓子系統的接口更加好用。

[設計模式][GOF] 24種設計模式概述

共享元素(Flyweight):

運用共享技術有效地支援大量細粒度的對象。

解釋器(Interpreter):

定義一個語言,定義它的文法表示,并定義一個解釋器,該解釋器使用該表示來解釋語言中的句子。

[設計模式][GOF] 24種設計模式概述

疊代器(Iterator):

提供對聚合對象的統一通路接口,不管聚合對象的内部資料結構是什麼樣的。

[設計模式][GOF] 24種設計模式概述

中介(Mediator):

用一個中介對象封裝一系列對象互動,這些被代理的對象不需要互相直接互動,全都通過中介來進行。

[設計模式][GOF] 24種設計模式概述

備忘錄(Memento):

在不破壞封裝性的前提下,捕獲一個對象的狀态并儲存這個狀态,這個狀态是一個執行個體,這樣友善之後切換狀态。

[設計模式][GOF] 24種設計模式概述

觀察者(Observer):

向某個被觀察對象注冊一些監聽者執行個體,當某個事件發生時,被觀察對象主動通知所有監聽者執行個體發生了什麼事情。實作起來很簡單,所有監聽者都繼承自同一個父類,同時實作父類的事件觸發函數,被觀察對象持有一個清單,裡面存儲N個父類指針,當事件發生時,被觀察對象周遊并調用清單中所有執行個體的事件處理虛函數。

[設計模式][GOF] 24種設計模式概述

原型(Prototype):

原型時一系列執行個體,如果想建立新的執行個體,那麼可以通過拷貝原型的方式來建立。

[設計模式][GOF] 24種設計模式概述

代理(Proxy):

對已有對象提供一個接口再封裝,如果已有對象的封裝性較差,那麼大部分情況下要采用Proxy進行再次封裝。

[設計模式][GOF] 24種設計模式概述

單例(Sigleton):

保證全局範圍内隻有一個執行個體。

狀态機(State):

對象根據業務功能的轉變而具備不同的狀态,以及可提供不同的服務。狀态機的實作多種多樣,不好一概而論。

[設計模式][GOF] 24種設計模式概述

政策(Strategy):

定義一系列算法,這些算法繼承自同一個基類,所有需要這些算法的執行個體都持有一個基類算法的引用,後期隻需要根據需要切換引用所指向的算法政策即可。這就是簡單的多态應用。

[設計模式][GOF] 24種設計模式概述

模闆方法(Template Method):

定義一個類,内含一套流程,流程中包含自定義的部分和多态的部分,這樣新的有流程便可以通過繼承的方式來獲得包含自定義多态的新流程模闆。

通路者(Visitor):