學習過設計模式的都知道,設計模式分為三大類,分別是:建立型、結構型、行為型。但為什麼它們這麼分呢?某個設計模式為啥就屬於結構型,而不屬於行為型呢?建立型、結構型、行為型它們到底有什麼不同呢?今天就來聊一聊我的理解。
建立型模式,顧名思義就是用來建立物件的。建立型模式包含的五個設計模式,分別是:
從它們的作用來看,它們全部都是建立新物件相關的模式。
工廠方法模式、抽象工廠模式、建造者模式都是建立新物件,可以遮蔽建立物件的細節。原型模式是進行物件轉殖,也算是新物件建立。單例模式是控制只能建立單個物件,其也包含了物件的建立,因此也算是建立型模式。
結構型模式,就是介紹如何將物件和類組裝成較大的結構,並同時保持結構的靈活和高效。結構型模式把乙個個物件結合在一起,就像積木搭建起來一樣,有一種結構化的感覺。結構型模式包含 7 個設計模式,分別是:
介面卡模式指的是可以讓不相容的物件能夠合作,通常情況是有乙個介面卡類實現了多個介面,從而在介面方法中寫入特定邏輯去做相容適配。這裡的結構體現在對於兩種物件的相容,通過相容將新老物件組合起來了。
橋梁模式其實就是把固定的和變化的分離開來,使用組合的方式去實現。將固定的放在原地不動,而變化的則抽離出去作為乙個新的類,再通過組合的形式被老的類引用。這裡的結構體現在舊類對新類的引用,它們之間變成了一種結構型關係。
組合模式就是多個結構組合起來,形成乙個更複雜的結構。組合模式更多是一種資料結構的呈現,而不能說是一種設計模式。但從廣義的設計模式定義來看,將組合模式說成是一種設計模式,也沒有錯。
大家會發現組合模式和橋梁模式非常像,其實這兩者之間並沒有太大的差別,甚至是說基本一樣。橋梁模式與組合模式,其實都是基於組合這種關係,不同的物件組合起來形成更大的結構體。橋梁模式是基於組合模式的。
門面模式指的是提供乙個全新的介面層,將子系統複雜的介面內容遮蔽了。則像是肯德基的前台一樣,幫你把一切複雜的東西遮蔽了。你不需要關心漢堡怎麼做,奧爾良雞翅怎麼做。你只需要告訴前台要吃什麼,它就會把漢堡、雞翅等東西做好了拿給你。
在門面模式中,我們在使用方與子系統之間插入了一層介面層,去遮蔽複雜的內部細節。就像是肯德基的前台,幫我們遮蔽了內部食物的製作細節一樣。門面模式的結構就體現在我們插入的這一層「門面」上,它將使用方與子系統連線起來,讓使用更方便了!
享元模式指的是共享同乙個元素,是一種節省記憶體的設計模式,其實就類似我們的池技術。與其他物件複雜的結構相比,我都不覺得享元模式是一種設計模式,而只是一種思想而已。但如果嚴格地從設計模式的定義來講的話,那其實也可以算是。
在享元模式中,我們會新增乙個類去儲存元素的對映池。而這個新增的類就相當於是乙個新增的物件,通過組合的形式去節省記憶體的消耗。享元模式的結構性更多是通過組合的形式體現的。
**模式其實就是乙個**卡在買賣雙方中間,做一些流程上的控制。**模式的結構性就體現在多了乙個**類,卡在「買賣雙方」中間,這種結構特徵不言而喻。
從上面我們的描述來看,我們可以知道結構型模式很多時候,就是兩者物件之間有乙個物件擋在中間,例如:介面卡模式、門面模式、**模式。要不就是通過某些關係組合在一起,例如:橋梁模式、組合模式、裝飾模式、享元模式。
要理解行為型模式,就要重點留意行為。雖然行為型模式有些點與結構型模式類似,但是其最大的特點是行為,是這個動起來的東西。
我們舉個例子:為什麼中介者模式屬於行為型模式,而**模式屬於結構型模式?
中介者模式聽起來與**模式很像,但中介者模式說的是做多個物件之間的協調工作,協調他們的行動!看到了嗎?協調他們的行動,才是中介者模式的核心,所以說中介者模式才是行為型模式。而**模式,則不會有那麼多個物件之間複雜的關係,其側重於對被**物件的控制。其重點不在於複雜的物件關係,不在於協調多個物件的工作,而在於單個物件的控制,**就像卡在兩者中間的乙個結構一樣。
有些朋友要說了,那其實**模式也有對**物件的控制這一行為啊,為什麼不能算是行為型模式呢?**模式確實有對**物件控制這一行為,但這裡要強調的是重點這個詞。這裡並不是說**模式就沒有行為,而是說**模式的行為比起結構性少,並且不是重點。而中介者模式肯定也有結構性的東西,但它誕生的目的就是為了協調多個子系統的複雜呼叫關係,協調關係才是中介者模式的重點。
行為型模式有 10 個設計模式,分別是:
責任鏈模式,是乙個個物件組合起來的物件鏈。其請求會從鏈頭傳到鏈尾,每個物件可以判斷其是否返回或傳遞到下乙個物件。其側重於是否返回或傳遞下去,重點是在這個行為的處理。所以責任鏈模式才叫行為型模式。
命令模式,是把要做的事情抽象起來,形成乙個命令。後續要做這個事情的時候,我直接給乙個命令你就知道我要做什麼了。為什麼要這麼做呢?因為變化!如果我們的命令有很多個,那麼每次我修改乙個命令,我就要修改發出命令和執行命令兩個地方。
但實際上發出命令的動作是不會變的,變化的只是執行命令的地方。於是為了隔離變化,那麼我們將執行命令這塊分離出去。那麼發出命令與執行命令怎麼溝通呢?答案是通過命令!這個其實就類似於餐廳前台與後廚的溝通。餐廳前台給的做選單就是乙個命令,後廚拿到這個命令之後就去執行。
可以看到在命令模式裡,其核心是拿到命令去執行,它們之間也是乙個行動的概念,因此命令模式也才歸屬於行為型模式。
迭代器模式,其實就是實現了集合所有元素的遍歷,讓你使用的時候不需要關心它底層的資料結構。其重點在於對集合元素的遍歷這個行為,所以歸屬於行為型模式。在現在基本上只存在於原始碼、框架中,實際工作用到的很少了。
中介者模式,前面說過了其側重於對多個物件之間的協調。其重點在於協調這個事情,所以其歸屬於行為型模式。
備忘錄模式,就是在某個時候把東西記下來,避免忘記了。在程式設計上,其實就是在某個時刻將物件的資訊記錄儲存下來,從而在另乙個時候可以恢復。其重點在於,其實現上會有乙個專門的類來幫你記錄下資訊,所以歸屬於行為型模式。
觀察者模式,從其名字可以知道有些人盯著你,需要知道你的動向,其實就是發布訂閱模式。其重點在於觀察這個動作,觀察之後將這個事情傳遞出去,你看到這些都是乙個個的動作,因此歸屬於行為型模式。
狀態模式,就是更為方便地控制狀態。如果乙個事物的狀態轉換比較複雜,那麼可以將其狀態抽離出來,單獨作為乙個類。這樣其狀態的變化就可以更好地控制,也分離了變化。這個就是狀態模式的應用。從名字來看,我們會覺得它應該是結構型模式,即包含某狀態嘛。但實際上,其側重於對於狀態更好地控制,所以歸屬於行為型模式。
策略模式,其實就是對於不同的東西,用不同的處理方式。一般情況下,單個具體的策略就是乙個類,而這些類都會實現這些策略共有的乙個介面。其重點在於不同東西,不同的處理方式。重點在於處理方式的不同,所以歸屬於行為型模式。
模板方法模式。這裡有兩個詞,即:模板、方法。模板指的是一套固定的東西,其實就是固定的額演算法。方法,表示這個模板是存放在方法上的。所以叫模板方法。簡單地說,模板方法其實就是父類定義了介面類的一些共有演算法。子類不能改變這個演算法流程,只能做有限的擴充套件。所以模板方法的重點是父類控制了一整套行為流程,其核心在於有一套固定了的演算法行為,所以叫行為型模式。
訪問者模式。訪問,即當你當成了外人,不想你隨便動。你要什麼,我弄好之後給你(呼叫你的方法)。其定義的還是訪問者與被訪問者之間應該如何溝通的問題,所以歸屬於行為型模式。
為什麼要費盡周折從分類上去說這些設計模式呢?因為這樣能更好地理解設計模式。乙個設計模式能歸屬於某個分類,我相信並不是巧合,肯定是因為其特性是符合這個分類的,不然不可能隨便地進行分類。
所以我們去研究為什麼這個模式歸屬於這個分類,可以更好地理解這個模式的本質,使得我們對這些設計模式有更好的理解。與此同時,我們在研究的過程也是深入理解的過程,也是對比的過程,不斷加深我們的理解與認知。
常用設計模式 深入理解模板模式
定義 定義乙個操作中的演算法的框架,而將一些步驟延遲到子類中,使得子類可以不改變乙個演算法的結構即可重定義該演算法的某些特定步驟。說到步驟,我想對於我們程式設計師來說,最熟悉的當然是乙個需求的乙個開發流程了,下面我們就從開發流程來了解模板模式。那麼開發流程具體有哪些步驟,請看 1.需求評審 產品,開...
深入理解設計模式(十) 命令模式
命令模式 command pattern 是一種資料驅動的設計模式,它屬於行為型模式。請求以命令的形式包裹在物件中,並傳給呼叫物件。呼叫物件尋找可以處理該命令的合適的物件,並把該命令傳給相應的物件,該物件執行命令。命令模式是乙個高內聚的模式,其定義為 將乙個請求封裝成乙個物件,從而讓你使用不同的請求...
深入理解設計模式(七) 建造者模式
建造者模式也稱生成器模式 定義 將乙個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示 依賴倒轉 產品類 一般是乙個較為複雜的物件,也就是說建立物件的過程比較複雜,一般會有比較多的 量。在本類圖中,產品類是乙個具體的類,而非抽象類。實際程式設計中,產品類可以是由乙個抽象類與它的不同...