解讀GoF的23鐘設計模式(濃縮版)

2021-08-08 10:13:20 字數 3435 閱讀 2299

今天看了一本gof的23鐘設計模式的書(pdf版本)。

這本書《設計模式精解-gof 23 種設計模式解析》已經比較精簡了。

本文相當於是筆記。

factory模式的這種功能是可以將多個子類的建立整合在一起。這樣使用者不需要關心建立的實現。你不需要知道他們到底是使用了不同的子類來實現還是用引數標記來實現。

factory模式的另一種功能是,可以用過不同的方法名來建立不同的物件,同樣起到隱藏實現的功能。

實際上這種封裝方式就像是對**的一種整合。比較2b的說法是,這樣比較好看。當然,他不可能真的僅僅只是好看。在後續使用和維護的過程中,使用factory模式會讓你的工作量減少n倍,並且更不容易出錯。

有n個子類,在不使用factory的情況下,遇到需要什麼子類,就直接建立這個子類。這樣看上去視乎邏輯清晰且簡單。

但是一旦需要更新,比如將n種子類變成n/2種(我們發現有兩個大類其實是可以整合在一起的)。這個時候如果在m個地方建立了這種型別,就得更改m次(不要說使用全文替換的方式,這種方式可能會產生更大的隱患。你以為他正常工作了,但是他可能會過多的替換,或者漏替換)。而使用factory模式,只需要更改factory即可。哪怕更改**的數量是一樣多的,factory模式也有他的優點:你可以很明確的知道要改**!

factory模式還可以將建立動作延後,我們可以在建立factory時就將引數某些引數確定。然後在需要的時候進行建立。這樣可以隱藏在此之前的具體初始化動作。你不需要知道在建立之前還有哪些初始化動作。

當然,你可以將所有與這個召喚物相關的引數都儲存下來,然後在需要的時候建立。如果我們對這種方式進行優化,將這些引數封裝到乙個物件中。實際上這就是比較原始的factory了。factory只是把一些可以在更早之前就確定的東西初始化。這樣可以避免每次都做重複的動作(比如每次都通過type switch到相應的子類)。

abstactfactory更像是factory模式對factoryobject的一種應用。只不過factory中一般只會用於建立一種類,而abstactfactory會建立多種類。所以將abstactfactory作為一種新的模式有些多餘,算是factory的一種公升級

單例模式的核心理念就是該類只有乙個物件。除此之外的所有問題都不是問題。

比如說我能不能使用該類型別的靜態成員變數,能不能使用全域性變數,能不能讓該類的所有變數和方法都變成靜態的來實現這一需求。能!

實際上單例模式就是使用靜態成員變數的方式實現的。

只要你覺得你實現的方式更好用,並且實現了單例模式的理念。那麼就是一種單例模式的實現。

一般情況下我們會將factory和singleton結合。

實際上只要是滿足:該類只有乙個物件的。都應該使用單例模式來實現。

單例模式會盡可能從根本上解決類有例項化多次的問題(通過破壞單例的原則,可以讓單例例項化多次,但這種操作不可能是意外產生)。

單例互相之間呼叫時,你不需要關心初始化順序的問題(當然單例不能解決初始化時迴圈呼叫的問題,單例a初始化是需要單例b,單例b初始化是間接需要單例a)。

單例在實現的過程中更自然(更自然的實現更容易理解,也更不易出錯)。

builder模式算是一種非常弱的模式(只是小小的技巧)。

builder模式讓我想起小時看的乙個動畫片。具體不清楚了,不過有個情景記憶深刻。

「組成腿和腳,組成軀幹和手臂,我來組成頭部。。。」

builder模式大致也是這個意思。將乙個object的初始化分成了幾個部分。可以在不同的時間,不同的地方,甚至是不同的人來實現他的某一部分的初始化。當所有部分都初始化後,就可以獲取到這個object了。

為類提供乙個複製自身的方法。這樣當你那當乙個基類物件clone的時候就不需要知道這個基類物件實際上是那個子類的物件。

橋接模式將多用組合型別連線在一起。如果我們要支援n種平台,m種實現。如果直接使用子類的方式你將產生m*n個子類。當然,在實際的開發過程中bridge模式的使用是自然而然的。當發現沒增加乙個類的實現是需要增加n個子類時,很自然的你就會想到使用乙個新的類,來整合多層變化。

介面封裝模式,將多種不同實現方式的介面封裝成乙個統一的介面。可以隱藏底層呼叫。多用於跨平台(不同平台的執行緒機制不一樣)和第三方庫(第三方的呼叫風格和現有的風格不一致)呼叫。

裝飾器模式,允許動態新增裝飾器,用來對某一方法的加強。比如我們對一斷文字進行加密時,我們可以餓使用多種裝飾器(加密方式)對其進行加密。當然在解密的時候需要是逆序的。

組合模式。隱藏結構特徵。你不需要知道該節點是葉子節點還是非葉子節點。舉個例子,給乙個人發工資或者給乙個部門發工資,還是給乙個小組發工資。對於發工資的人是不在乎拿錢的是人還是部門或是小組,他只想知道要發多少錢。至於內部真麼發他就不管了。

共享模式,將一些會被多個地方使用的共有的資料作為乙個共享的object。比如有很多顆聖誕樹(裡面的樹是完全一樣的,詭異的很),我們將他擺放在不同的地方,房間裡走廊裡面,房子外面。放在不同地方的用不同的裝飾物品。這個時候對樹本身的描述是一致的,但是他的位置和裝飾物不一致。

不得不說的是,一般情況下,我們還需要乙個object來管理這些共享的object(不然你不知道是要new乙個出來,還是使用已有的)。而這個object一般就是乙個單例。同時這個manager還可以是乙個factory。

外觀模式。將子系統中的一組操作封裝成乙個api。(是個人都知道會這麼做啊,還專門搞個設計模式,裝逼裝到家了)

模版模式,將基礎的邏輯實現隱藏起來。這個模式應該是使用最為頻繁的了。std::vector,std::list,std::map,std::set。就算沒用過也肯定聽過吧。

策略模式。將功能的多樣性封裝成object。以便在執行的過程中進行組裝。

狀態模式。狀態機知道不,不同的狀態下使用不用的實現。

ob模式,監聽某些事件,並做出相應的處理。監聽者應該允許被動態的新增活刪除。

備忘錄模式。該模式允許將乙個object的當前狀態儲存下來,並可以通過這個儲存的object對其狀態進行恢復。(這是乙個想當然的設計模式,我們當然想在任何時候都反悔上一次操作,為了實現這一功能,在極端的情況下,你的記憶體資源消耗需要*2)。

中介者模式,將呼叫和實現雙方都隱藏。對於通訊模組有相當好的效果。

命令模式,將引數和引數明隱藏起來。

訪問者模式,將乙個資料object的操作封裝起來。這樣當你更新操作方式的時候可以和原有資料無關。

責任鏈模式,處理乙個事件,或者(實際上也可以及處理還傳遞)將其傳遞給後續的節點處理。

你可以去用用std::list,std::map,std::vector,std::set。迭代模式就是實現迭代器功能。

直譯器模式。解析指令碼。每乙個直譯器的實現,都是一種新的指令碼語言的發明(是不是很屌)。

其實設計模式只是一些程式設計的技巧。不是說一定要使用某種設計模式。但是當你被某個問題所煩惱或者你預期某種麻煩的時候,你所想的解決方案大致也會趨向與現有的設計模式。所以你可以熟練的掌握這些模式,當你遇到問題的時候使用這些模式的核心思想。最後產生一種解決方案,或者是和某種模式基本一致,或是幾種模式的結合體,或是再參雜一些自己的理解,這些結果都是極好的。設計模式更像是前人總結的經驗,他可能已經不再適用於現在的環境,但是了解他的原理說不定會對你建立一種新的模式給與靈感!

GOF23 設計模式

design patterns elements of reusable object oriented software 即後述 設計模式 一書 由 erich gamma richard helm ralph johnson 和 john vlissides 合著 addison wesley,...

設計模式GOF23 工廠模式

簡單工廠模式 static factory method 是建立者模式的一種,是負責建立物件的模式。工廠模式是為了實現建立物件和呼叫物件分離的需求。簡單工廠用來生產同一等級結構中的任意產品。對於新增的產品需要修改已有 工廠方法模式用來生產同意等級結構中的固定產品。支援增加任意產品 抽象工廠模式用來生...

設計模式GOF23 外觀模式

外觀模式 facade 是結構性模式的一種,也有人稱它為門面模式。結構型模式的核心作用是從程式的結構上實現低耦合,從而可以擴大整體的類結構,用來解決更大的問題。外觀模式的核心就是為子系統提供統一的入口,封裝系統的複雜性,便於客戶端呼叫。外觀角色 在客戶端可以呼叫它的方法,它會把客戶端呼叫需要的操作放...