1. 程式人生 > 程式設計 >Java設計模式之23種設計模式詳解

Java設計模式之23種設計模式詳解

一、什麼是設計模式

設計模式(Design pattern)是一套被反覆使用、多數人知曉的、經過分類編目的、程式碼設計經驗的總結。使用設計模式是為了可重用程式碼、讓程式碼更容易被他人理解、保證程式碼可靠性。 毫無疑問,設計模式於己於他人於系統都是多贏的,設計模式使程式碼編制真正工程化,設計模式是軟體工程的基石,如同大廈的一塊塊磚石一樣。專案中合理的運用設計模式可以完美的解決很多問題,每種模式在現在中都有相應的原理來與之對應,每一個模式描述了一個在我們周圍不斷重複發生的問題,以及該問題的核心解決方案,這也是它能被廣泛應用的原因。簡單說:

模式:在某些場景下,針對某類問題的某種通用的解決方案。

場景:專案所在的環境

問題:約束條件,專案目標等

解決方案:通用、可複用的設計,解決約束達到目標。

二、設計模式的三個分類

建立型模式:物件例項化的模式,建立型模式用於解耦物件的例項化過程。

結構型模式:把類或物件結合在一起形成一個更大的結構。

行為型模式:類和物件如何互動,及劃分責任和演算法。

如下圖所示:

Java設計模式之23種設計模式詳解

三、各分類中模式的關鍵點

單例模式:某個類只能有一個例項,提供一個全域性的訪問點。

簡單工廠:一個工廠類根據傳入的參量決定創建出那一種產品類的例項。

工廠方法:定義一個建立物件的介面,讓子類決定例項化那個類。

抽象工廠:建立相關或依賴物件的家族,而無需明確指定具體類。

建造者模式:封裝一個複雜物件的構建過程,並可以按步驟構造。

原型模式:通過複製現有的例項來建立新的例項。

介面卡模式:將一個類的方法介面轉換成客戶希望的另外一個介面。

組合模式:將物件組合成樹形結構以表示“”部分-整體“”的層次結構。

裝飾模式:動態的給物件新增新的功能。

代理模式:為其他物件提供一個代理以便控制這個物件的訪問。

亨元(蠅量)模式:通過共享技術來有效的支援大量細粒度的物件。

外觀模式:對外提供一個統一的方法,來訪問子系統中的一群介面。

橋接模式:將抽象部分和它的實現部分分離,使它們都可以獨立的變化。

模板模式:定義一個演算法結構,而將一些步驟延遲到子類實現。

直譯器模式:給定一個語言,定義它的文法的一種表示,並定義一個直譯器。

策略模式:定義一系列演算法,把他們封裝起來,並且使它們可以相互替換。

狀態模式:允許一個物件在其物件內部狀態改變時改變它的行為。

觀察者模式:物件間的一對多的依賴關係。

備忘錄模式:在不破壞封裝的前提下,保持物件的內部狀態。

中介者模式:用一箇中介物件來封裝一系列的物件互動。

命令模式:將命令請求封裝為一個物件,使得可以用不同的請求來進行引數化。

訪問者模式:在不改變資料結構的前提下,增加作用於一組物件元素的新功能。

責任鏈模式:將請求的傳送者和接收者解耦,使的多個物件都有處理這個請求的機會。

迭代器模式:一種遍歷訪問聚合物件中各個元素的方法,不暴露該物件的內部結構。

四、概說23種設計模式

1.單例模式

單例模式,它的定義就是確保某一個類只有一個例項,並且提供一個全域性訪問點。

單例模式具備典型的3個特點:1、只有一個例項。2、自我例項化。3、提供全域性訪問點。

因此當系統中只需要一個例項物件或者系統中只允許一個公共訪問點,除了這個公共訪問點外,不能通過其他訪問點訪問該例項時,可以使用單例模式。

單例模式的主要優點就是節約系統資源、提高了系統效率,同時也能夠嚴格控制客戶對它的訪問。也許就是因為系統中只有一個例項,這樣就導致了單例類的職責過重,違背了“單一職責原則”,同時也沒有抽象類,所以擴充套件起來有一定的困難。其UML結構圖非常簡單,就只有一個類,如下圖:

Java設計模式之23種設計模式詳解

2.工廠方法模式

作為抽象工廠模式的孿生兄弟,工廠方法模式定義了一個建立物件的介面,但由子類決定要例項化的類是哪一個,也就是說工廠方法模式讓例項化推遲到子類。

工廠方法模式非常符合“開閉原則”,當需要增加一個新的產品時,我們只需要增加一個具體的產品類和與之對應的具體工廠即可,無須修改原有系統。同時在工廠方法模式中使用者只需要知道生產產品的具體工廠即可,無須關係產品的建立過程,甚至連具體的產品類名稱都不需要知道。雖然他很好的符合了“開閉原則”,但是由於每新增一個新產品時就需要增加兩個類,這樣勢必會導致系統的複雜度增加。其UML結構圖:

Java設計模式之23種設計模式詳解

3.抽象工廠模式

所謂抽象工廠模式就是提供一個介面,用於建立相關或者依賴物件的家族,而不需要明確指定具體類。他允許客戶端使用抽象的介面來建立一組相關的產品,而不需要關係實際產出的具體產品是什麼。這樣一來,客戶就可以從具體的產品中被解耦。它的優點是隔離了具體類的生成,使得客戶端不需要知道什麼被建立了,而缺點就在於新增新的行為會比較麻煩,因為當新增一個新的產品物件時,需要更加需要更改介面及其下所有子類。其UML結構圖如下:

Java設計模式之23種設計模式詳解

4.建造者模式

對於建造者模式而已,它主要是將一個複雜物件的構建與表示分離,使得同樣的構建過程可以建立不同的表示。適用於那些產品物件的內部結構比較複雜。

建造者模式將複雜產品的構建過程封裝分解在不同的方法中,使得建立過程非常清晰,能夠讓我們更加精確的控制複雜產品物件的建立過程,同時它隔離了複雜產品物件的建立和使用,使得相同的建立過程能夠建立不同的產品。但是如果某個產品的內部結構過於複雜,將會導致整個系統變得非常龐大,不利於控制,同時若幾個產品之間存在較大的差異,則不適用建造者模式,畢竟這個世界上存在相同點大的兩個產品並不是很多,所以它的使用範圍有限。其UML結構圖:

Java設計模式之23種設計模式詳解

5.原型模式

在我們應用程式可能有某些物件的結構比較複雜,但是我們又需要頻繁的使用它們,如果這個時候我們來不斷的新建這個物件勢必會大大損耗系統記憶體的,這個時候我們需要使用原型模式來對這個結構複雜又要頻繁使用的物件進行克隆。所以原型模式就是用原型例項指定建立物件的種類,並且通過複製這些原型建立新的物件。

它主要應用與那些建立新物件的成本過大時。它的主要優點就是簡化了新物件的建立過程,提高了效率,同時原型模式提供了簡化的建立結構。UML結構圖:

Java設計模式之23種設計模式詳解

模式結構
原型模式包含如下角色:
Prototype:抽象原型類
ConcretePrototype:具體原型類
Client:客戶類

6.介面卡模式

在我們的應用程式中我們可能需要將兩個不同介面的類來進行通訊,在不修改這兩個的前提下我們可能會需要某個中介軟體來完成這個銜接的過程。這個中介軟體就是介面卡。所謂介面卡模式就是將一個類的介面,轉換成客戶期望的另一個介面。它可以讓原本兩個不相容的介面能夠無縫完成對接。

作為中介軟體的介面卡將目標類和適配者解耦,增加了類的透明性和可複用性。

Java設計模式之23種設計模式詳解

介面卡模式包含如下角色:
Target:目標抽象類
Adapter:介面卡類
Adaptee:適配者類
Client:客戶類

7.橋接模式

如果說某個系統能夠從多個角度來進行分類,且每一種分類都可能會變化,那麼我們需要做的就是講這多個角度分離出來,使得他們能獨立變化,減少他們之間的耦合,這個分離過程就使用了橋接模式。所謂橋接模式就是講抽象部分和實現部分隔離開來,使得他們能夠獨立變化。

橋接模式將繼承關係轉化成關聯關係,封裝了變化,完成了解耦,減少了系統中類的數量,也減少了程式碼量。

Java設計模式之23種設計模式詳解

橋接模式包含如下角色:
Abstraction:抽象類
RefinedAbstraction:擴充抽象類
Implementor:實現類介面
ConcreteImplementor:具體實現類

8.組合模式

組合模式組合多個物件形成樹形結構以表示“整體-部分”的結構層次。它定義瞭如何將容器物件和葉子物件進行遞迴組合,使得客戶在使用的過程中無須進行區分,可以對他們進行一致的處理。在使用組合模式中需要注意一點也是組合模式最關鍵的地方:葉子物件和組合物件實現相同的介面。這就是組合模式能夠將葉子節點和物件節點進行一致處理的原因。

雖然組合模式能夠清晰地定義分層次的複雜物件,也使得增加新構件也更容易,但是這樣就導致了系統的設計變得更加抽象,如果系統的業務規則比較複雜的話,使用組合模式就有一定的挑戰了。

Java設計模式之23種設計模式詳解

模式結構
組合模式包含如下角色:
Component: 抽象構件
Leaf: 葉子構件
Composite: 容器構件
Client: 客戶類

9.裝飾模式

我們可以通過繼承和組合的方式來給一個物件新增行為,雖然使用繼承能夠很好擁有父類的行為,但是它存在幾個缺陷:一、物件之間的關係複雜的話,系統變得複雜不利於維護。二、容易產生“類爆炸”現象。三、是靜態的。在這裡我們可以通過使用裝飾者模式來解決這個問題。

裝飾者模式,動態地將責任附加到物件上。若要擴充套件功能,裝飾者提供了比繼承更加有彈性的替代方案。雖然裝飾者模式能夠動態將責任附加到物件上,但是他會產生許多的細小物件,增加了系統的複雜度。

Java設計模式之23種設計模式詳解

模式結構
裝飾模式包含如下角色:
Component: 抽象構件
ConcreteComponent: 具體構件
Decorator: 抽象裝飾類
ConcreteDecorator: 具體裝飾類

10.外觀模式

我們都知道類與類之間的耦合越低,那麼可複用性就越好,如果兩個類不必彼此通訊,那麼就不要讓這兩個類發生直接的相互關係,如果需要呼叫裡面的方法,可以通過第三者來轉發呼叫。外觀模式非常好的詮釋了這段話。外觀模式提供了一個統一的介面,用來訪問子系統中的一群介面。它讓一個應用程式中子系統間的相互依賴關係減少到了最少,它給子系統提供了一個簡單、單一的屏障,客戶通過這個屏障來與子系統進行通訊。通過使用外觀模式,使得客戶對子系統的引用變得簡單了,實現了客戶與子系統之間的鬆耦合。但是它違背了“開閉原則”,因為增加新的子系統可能需要修改外觀類或客戶端的原始碼。

Java設計模式之23種設計模式詳解

外觀模式包含如下角色:
Facade: 外觀角色
SubSystem:子系統角色

11.亨元模式

在一個系統中物件會使得記憶體佔用過多,特別是那些大量重複的物件,這就是對系統資源的極大浪費。享元模式對物件的重用提供了一種解決方案,它使用共享技術對相同或者相似物件實現重用。享元模式就是執行共享技術有效地支援大量細粒度物件的複用。系統使用少量物件,而且這些都比較相似,狀態變化小,可以實現物件的多次複用。這裡有一點要注意:享元模式要求能夠共享的物件必須是細粒度物件。享元模式通過共享技術使得系統中的物件個數大大減少了,同時享元模式使用了內部狀態和外部狀態,同時外部狀態相對獨立,不會影響到內部狀態,所以享元模式能夠使得享元物件在不同的環境下被共享。同時正是分為了內部狀態和外部狀態,享元模式會使得系統變得更加複雜,同時也會導致讀取外部狀態所消耗的時間過長。

Java設計模式之23種設計模式詳解

享元模式包含如下角色:
Flyweight: 抽象享元類
ConcreteFlyweight: 具體享元類
UnsharedConcreteFlyweight: 非共享具體享元類
FlyweightFactory: 享元工廠類

12.代理模式

代理模式就是給一個物件提供一個代理,並由代理物件控制對原物件的引用。它使得客戶不能直接與真正的目標物件通訊。代理物件是目標物件的代表,其他需要與這個目標物件打交道的操作都是和這個代理物件在交涉。

代理物件可以在客戶端和目標物件之間起到中介的作用,這樣起到了的作用和保護了目標物件的,同時也在一定程度上面減少了系統的耦合度。

Java設計模式之23種設計模式詳解

代理模式包含如下角色:
oSubject: 抽象主題角色
oProxy: 代理主題角色
oRealSubject: 真實主題角色

13.訪問者模式

訪問者模式俗稱23大設計模式中最難的一個。除了結構複雜外,理解也比較難。在我們軟體開發中我們可能會對同一個物件有不同的處理,如果我們都做分別的處理,將會產生災難性的錯誤。對於這種問題,訪問者模式提供了比較好的解決方案。訪問者模式即表示一個作用於某物件結構中的各元素的操作,它使我們可以在不改變各元素的類的前提下定義作用於這些元素的新操作。

訪問者模式的目的是封裝一些施加於某種資料結構元素之上的操作,一旦這些操作需要修改的話,接受這個操作的資料結構可以保持不變。為不同型別的元素提供多種訪問操作方式,且可以在不修改原有系統的情況下增加新的操作方式。同時我們還需要明確一點那就是訪問者模式是適用於那些資料結構比較穩定的,因為他是將資料的操作與資料結構進行分離了,如果某個系統的資料結構相對穩定,但是操作演算法易於變化的話,就比較適用適用訪問者模式,因為訪問者模式使得演算法操作的增加變得比較簡單了。

Java設計模式之23種設計模式詳解

訪問者模式包含如下角色:
Vistor: 抽象訪問者
ConcreteVisitor: 具體訪問者
Element: 抽象元素
ConcreteElement: 具體元素
ObjectStructure: 物件結構

14.模板模式

有些時候我們做某幾件事情的步驟都差不多,僅有那麼一小點的不同,在軟體開發的世界裡同樣如此,如果我們都將這些步驟都一一做的話,費時費力不討好。所以我們可以將這些步驟分解、封裝起來,然後利用繼承的方式來繼承即可,當然不同的可以自己重寫實現嘛!這就是模板方法模式提供的解決方案。

所謂模板方法模式就是在一個方法中定義一個演算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以在不改變演算法結構的情況下,重新定義演算法中的某些步驟。

模板方法模式就是基於繼承的程式碼複用技術的。在模板方法模式中,我們可以將相同部分的程式碼放在父類中,而將不同的程式碼放入不同的子類中。也就是說我們需要宣告一個抽象的父類,將部分邏輯以具體方法以及具體建構函式的形式實現,然後宣告一些抽象方法讓子類來實現剩餘的邏輯,不同的子類可以以不同的方式來實現這些邏輯。所以模板方法的模板其實就是一個普通的方法,只不過這個方法是將演算法實現的步驟封裝起來的。

Java設計模式之23種設計模式詳解

模板方法模式包含如下角色:
AbstractClass: 抽象類
ConcreteClass: 具體子類

15.策略模式

我們知道一件事可能會有很多種方式來實現它,但是其中總有一種最高效的方式,在軟體開發的世界裡面同樣如此,我們也有很多中方法來實現一個功能,但是我們需要一種簡單、高效的方式來實現它,使得系統能夠非常靈活,這就是策略模式。

所以策略模式就是定義了演算法族,分別封裝起來,讓他們之前可以互相轉換,此模式然該演算法的變化獨立於使用演算法的客戶。

在策略模式中它將這些解決問題的方法定義成一個演算法群,每一個方法都對應著一個具體的演算法,這裡的一個演算法我就稱之為一個策略。雖然策略模式定義了演算法,但是它並不提供演算法的選擇,即什麼演算法對於什麼問題最合適這是策略模式所不關心的,所以對於策略的選擇還是要客戶端來做。客戶必須要清楚的知道每個演算法之間的區別和在什麼時候什麼地方使用什麼策略是最合適的,這樣就增加客戶端的負擔。

同時策略模式也非常完美的符合了“開閉原則”,使用者可以在不修改原有系統的基礎上選擇演算法或行為,也可以靈活地增加新的演算法或行為。但是一個策略對應一個類將會是系統產生很多的策略類。

Java設計模式之23種設計模式詳解

策略模式包含如下角色:
Context: 環境類
Strategy: 抽象策略類
ConcreteStrategy: 具體策略類

16.狀態模式

在很多情況下我們物件的行為依賴於它的一個或者多個變化的屬性,這些可變的屬性我們稱之為狀態,也就是說行為依賴狀態,即當該物件因為在外部的互動而導致他的狀態發生變化,從而它的行為也會做出相應的變化。對於這種情況,我們是不能用行為來控制狀態的變化,而應該站在狀態的角度來思考行為,即是什麼狀態就要做出什麼樣的行為。這個就是狀態模式。

所以狀態模式就是允許物件在內部狀態發生改變時改變它的行為,物件看起來好像修改了它的類。

在狀態模式中我們可以減少大塊的if…else語句,它是允許態轉換邏輯與狀態物件合成一體,但是減少if…else語句的代價就是會換來大量的類,所以狀態模式勢必會增加系統中類或者物件的個數。

同時狀態模式是將所有與某個狀態有關的行為放到一個類中,並且可以方便地增加新的狀態,只需要改變物件狀態即可改變物件的行為。但是這樣就會導致系統的結構和實現都會比較複雜,如果使用不當就會導致程式的結構和程式碼混亂,不利於維護。

Java設計模式之23種設計模式詳解

狀態模式包含如下角色:
Context: 環境類
State: 抽象狀態類
ConcreteState: 具體狀態類

17.觀察者模式

何謂觀察者模式?觀察者模式定義了物件之間的一對多依賴關係,這樣一來,當一個物件改變狀態時,它的所有依賴者都會收到通知並且自動更新。

在這裡,發生改變的物件稱之為觀察目標,而被通知的物件稱之為觀察者。一個觀察目標可以對應多個觀察者,而且這些觀察者之間沒有相互聯絡,所以麼可以根據需要增加和刪除觀察者,使得系統更易於擴充套件。所以觀察者提供了一種物件設計,讓主題和觀察者之間以鬆耦合的方式結合。

Java設計模式之23種設計模式詳解

觀察者模式包含如下角色:
Subject: 目標
ConcreteSubject: 具體目標
Observer: 觀察者
ConcreteObserver: 具體觀察者

18.備忘錄模式

後悔藥人人都想要,但是事實卻是殘酷的,根本就沒有後悔藥可買,但是也不僅如此,在軟體的世界裡就有後悔藥!備忘錄模式就是一種後悔藥,它給我們的軟體提供後悔藥的機制,通過它可以使系統恢復到某一特定的歷史狀態。

所謂備忘錄模式就是在不破壞封裝的前提下,捕獲一個物件的內部狀態,並在該物件之外儲存這個狀態,這樣可以在以後將物件恢復到原先儲存的狀態。它實現了對資訊的封裝,使得客戶不需要關心狀態儲存的細節。儲存就要消耗資源,所以備忘錄模式的缺點就在於消耗資源。如果類的成員變數過多,勢必會佔用比較大的資源,而且每一次儲存都會消耗一定的記憶體。

Java設計模式之23種設計模式詳解

備忘錄模式包含如下角色:
Originator: 原發器
Memento: 備忘錄
Caretaker: 負責人

19.中介者模式

租房各位都有過的經歷吧!在這個過程中中介結構扮演著很重要的角色,它在這裡起到一箇中間者的作用,給我們和房主互相傳遞資訊。在外面軟體的世界裡同樣需要這樣一箇中間者。在我們的系統中有時候會存在著物件與物件之間存在著很強、複雜的關聯關係,如果讓他們之間有直接的聯絡的話,必定會導致整個系統變得非常複雜,而且可擴充套件性很差!在前面我們就知道如果兩個類之間沒有不必彼此通訊,我們就不應該讓他們有直接的關聯關係,如果實在是需要通訊的話,我們可以通過第三者來轉發他們的請求。同樣,這裡我們利用中介者來解決這個問題。

所謂中介者模式就是用一箇中介物件來封裝一系列的物件互動,中介者使各物件不需要顯式地相互引用,從而使其耦合鬆散,而且可以獨立地改變它們之間的互動。在中介者模式中,中介物件用來封裝物件之間的關係,各個物件可以不需要知道具體的資訊通過中介者物件就可以實現相互通訊。它減少了物件之間的互相關係,提供了系統可複用性,簡化了系統的結構。

在中介者模式中,各個物件不需要互相知道了解,他們只需要知道中介者物件即可,但是中介者物件就必須要知道所有的物件和他們之間的關聯關係,正是因為這樣就導致了中介者物件的結構過於複雜,承擔了過多的職責,同時它也是整個系統的核心所在,它有問題將會導致整個系統的問題。所以如果在系統的設計過程中如果出現“多對多”的複雜關係群時,千萬別急著使用中介者模式,而是要仔細思考是不是您設計的系統存在問題。

Java設計模式之23種設計模式詳解

Mediator: 抽象中介者
ConcreteMediator: 具體中介者
Colleague: 抽象同事類
ConcreteColleague: 具體同事類

20.迭代器模式

對於迭代在程式設計過程中我們經常用到,能夠遊走於聚合內的每一個元素,同時還可以提供多種不同的遍歷方式,這就是迭代器模式的設計動機。在我們實際的開發過程中,我們可能會需要根據不同的需求以不同的方式來遍歷整個物件,但是我們又不希望在聚合物件的抽象介面中充斥著各種不同的遍歷操作,於是我們就希望有某個東西能夠以多種不同的方式來遍歷一個聚合物件,這時迭代器模式出現了。

何為迭代器模式?所謂迭代器模式就是提供一種方法順序訪問一個聚合物件中的各個元素,而不是暴露其內部的表示。迭代器模式是將迭代元素的責任交給迭代器,而不是聚合物件,我們甚至在不需要知道該聚合物件的內部結構就可以實現該聚合物件的迭代。

通過迭代器模式,使得聚合物件的結構更加簡單,它不需要關注它元素的遍歷,只需要專注它應該專注的事情,這樣就更加符合單一職責原則了。

Java設計模式之23種設計模式詳解

迭代器模式包含如下角色:
Iterator: 抽象迭代器
ConcreteIterator: 具體迭代器
Aggregate: 抽象聚合類
ConcreteAggregate: 具體聚合類

21.直譯器模式

所謂直譯器模式就是定義語言的文法,並且建立一個直譯器來解釋該語言中的句子。直譯器模式描述瞭如何構成一個簡單的語言直譯器,主要應用在使用面嚮物件語言開發的編譯器中。它描述瞭如何為簡單的語言定義一個文法,如何在該語言中表示一個句子,以及如何解釋這些句子。

Java設計模式之23種設計模式詳解

直譯器模式包含如下角色:
AbstractExpression: 抽象表示式
TerminalExpression: 終結符表示式
NonterminalExpression: 非終結符表示式
Context: 環境類
Client: 客戶類

22.命令模式

有些時候我們想某個物件傳送一個請求,但是我們並不知道該請求的具體接收者是誰,具體的處理過程是如何的,們只知道在程式執行中指定具體的請求接收者即可,對於這樣將請求封裝成物件的我們稱之為命令模式。所以命令模式將請求封裝成物件,以便使用不同的請求、佇列或者日誌來引數化其他物件。同時命令模式支援可撤銷的操作。

命令模式可以將請求的傳送者和接收者之間實現完全的解耦,傳送者和接收者之間沒有直接的聯絡,傳送者只需要知道如何傳送請求命令即可,其餘的可以一概不管,甚至命令是否成功都無需關心。同時我們可以非常方便的增加新的命令,但是可能就是因為方便和對請求的封裝就會導致系統中會存在過多的具體命令類。

Java設計模式之23種設計模式詳解

命令模式包含如下角色:
Command: 抽象命令類
ConcreteCommand: 具體命令類
Invoker: 呼叫者
Receiver: 接收者
Client:客戶類

23.責任鏈模式

職責鏈模式描述的請求如何沿著物件所組成的鏈來傳遞的。它將物件組成一條鏈,傳送者將請求發給鏈的第一個接收者,並且沿著這條鏈傳遞,直到有一個物件來處理它或者直到最後也沒有物件處理而留在鏈末尾端。

避免請求傳送者與接收者耦合在一起,讓多個物件都有可能接收請求,將這些物件連線成一條鏈,並且沿著這條鏈傳遞請求,直到有物件處理它為止,這就是職責鏈模式。在職責鏈模式中,使得每一個物件都有可能來處理請求,從而實現了請求的傳送者和接收者之間的解耦。同時職責鏈模式簡化了物件的結構,它使得每個物件都只需要引用它的後繼者即可,而不必瞭解整條鏈,這樣既提高了系統的靈活性也使得增加新的請求處理類也比較方便。但是在職責鏈中我們不能保證所有的請求都能夠被處理,而且不利於觀察執行時特徵。

Java設計模式之23種設計模式詳解

職責鏈模式包含如下角色:
Handler: 抽象處理者
ConcreteHandler: 具體處理者
Client: 客戶類

五、如何學習設計模式

說明,《如何學習設計模式》轉摘自:http://blog.csdn.net/yqj2065/article/details/39103857

①學習技巧

學習設計模式時,有一些技巧能夠幫助你快速理解設計模式。

a) 使用較簡單的面向物件的語言如Java、C#。GoF的[設計模式]實質上是面向物件的設計模式。[GoF·1.1]中提到“程式設計語言的選擇非常重要,它將影響人們理解問題的出發點”。從學習設計模式的角度看,Java和C#較C++更容易一些。比如Java介面等,能夠更有效展現設計模式的意圖。

b) 使用工具BlueJ。BlueJ最大的好處,就是提供了簡單的類圖。正如我在簡明設計模式Java中所做的,較少去專門畫類圖,而是在BlueJ中截圖。在學生上機編寫演示程式時,常常先看他的類圖,以判斷他的程式是否正確,必要時再看原始碼。

c) 日常生活的隱喻。用一些實際生活中的例子來說明某某模式,能夠讓你快速掌握某模式的目的和實現程式碼的結構。同時,你要認識到,這種隱喻如同告訴你(2+3)2=22+2*2*3+32,你需要自己舉一反三,得出(a+b)2=a2+2ab+b2。在實際工作中的模式的具體應用,則相當於應用代數公式。

d) 動手實踐和懷疑精神。看顯淺的參考書或上網查閱資料時,要自己敲(複製也可以)程式碼並執行,要多修改別人的原始碼提出自己的觀點:為什麼書中不這樣設計、為什麼要那樣設計;如果增添一些方法、方法引數、或成員變數會如何?必須要自己親自動手,最起碼要執行。另外,要敢於向博主提問、拍磚。你甚至可以質疑GoF的某些章節的解說和意圖,更何況一些博主呢。

②基礎知識

這些知識讓你知道,設計模式好在何處。

a)面向物件正規化。也就是人們傳說的思想。封裝、繼承和多型這些東西,在我看來比if、for等稍微高一點,也屬於語法問題。面向物件程式設計要掌握的三大原則是柏拉圖(Plato)原則、里氏(Liskov)替換原則和Parnas原則。這三個原則其實非常簡單。任何原則,你覺得很難一見鍾情,很難快速認同,那它就不會是好原則。

b)設計原則。許多人列舉了7大原則,如單一職責原則、開閉原則、里氏代換原則、依賴倒轉原則、介面隔離原則、合成複用原則、迪米特法則。LSP,我將它提升為面向物件正規化的3大基石之一;單一職責和介面隔離,主要作為面向物件分析/OOA時職責劃分所遵循的原則,此時你可以不太在意。依賴倒轉原則,我把它作為垃圾扔掉,因為開閉原則或者直接地說“依賴於抽象型別原則”已經包含了依賴倒轉原則的精華,而依賴倒轉原則的糟粕由IoC繼承。當然,回撥,我很強調。所以,你要掌握的有抽象依賴原則(OCP)、單向依賴原則(含對回撥的學習)和最低依賴原則(合成複用原則、迪米特法則)。

c) UML的初步瞭解。這是學習設計模式的工具。在早期,你甚至可以僅瞭解BlueJ的相關圖示,也就10分鐘的事情。

③境界

《五燈會元》卷十七中,有一則唐朝禪師青原惟信禪師的語錄:“老僧三十年前未參禪時,見山是山,見水是水。及至後來親見知識,有個入處,見山不是山,見水不是水。而今得個休歇處,依前見山只是山,見水只是水。”

a) 仔細研究GoF的[設計模式],逐個學習其意圖和結構,是一個抱著字典學習英語的方式。見山是山,見水是水,導致你可能在實際工作中生搬硬套、東施效顰。

b) 建議從簡單的場景出發,自己發現或設計出某種模式。你從中體會該模式是如何解決問題的,這樣,該模式成為你自己的東西,你才不會出現知易行難的問題。所有的設計模式不過是基本原則和理念在特定場合的應用。你可能不知道某個設計模式的名字,但是你知道它一切的優缺點和變體以及應用場合。見山不是山,見水不是水。

c) 你對基本原則和理念融會貫通,你可以惋惜:“我找到一種模式,原來在[設計模式](其實是某個特殊的書、文章提到的模式)中早就有了這種模式”。這時,模式不模式又如何呢?反模式又怎樣。看見一個模式,你會說:“嗯,這是一種有用的模式”。見山只是山,見水只是水。

以上一點淺見。

注:【】中的內容是我加的。

1轉錄【IT168知識庫】

發現很多初學設計模式的人都有一些特點就是學習了某個設計模式之後,貌似理解了,但是卻不知道怎麼去使用這些所謂的精華經驗,苦於不知如何下手。我最初學習設計模式的時候也有類似的經驗,我將我的經驗分享出來,希望能對初學者有幫助。

我對設計模式產生興趣是在大概一年以前,最初看書的時候好像是看懂了,大概知道他在說什麼。看了幾個模式之後就開始尋找時機來套用套用這些模式。結果是除了Singleton模式以外的其他模式都沒有找到應用的場所。然後我就沒開始看下去了,我知道再看也沒用,但是我並沒有放棄對設計模式的關注。

不久我就在MSDN的Webcast上看到李建忠的 C#面向物件設計模式縱橫談講座,很不錯的系列講座,讓我對設計模式有了新的理解。我意識到學習設計模式,確切的講是學習面向物件的設計模式,應該從學習面向物件開始。【面向物件的原理如同瞭解下象棋的規則,而設計模式相當於殘局,不知道規則看什麼殘局】由於之前一年都在做asp.net開發,雖然都是在寫類、學著duwamish搞分層架構、搞型別化DataSet、也弄過自定義實體類,但好像一年下來還沒怎麼用過介面,什麼多型也是極少用。事實上對面向物件的程式設計思想的認識還是很模糊的。

重新認識OO:面向物件程式設計是一種思想,以面向物件的思維來思考軟體設計結構,從而強化面向物件的程式設計正規化。面向物件的特點是封裝,繼承,多型【這些也算?】。所以從那是開始,當我設計一個類的時候,不斷的提示自己以下三點:
第一:別把自己的資料公開,除非你要向別人提供資料,使用盡量低的訪問許可權。
第二:以一個外部的視角來看類,緊記不要要求別人要在知道你是怎麼實現一個方法之後才能使用我的類。
第三:分清類的職責,該這個類做的事情就要在這個類中實現,不該我的類做的事情就讓別的類去實現。
在這三點的指導下來寫類,寫程式開始像在做“設計”了^_^。
一段時間後對設計模式就慢慢有感覺了,並能夠找到一些設計模式的應用場景了。並常套用套用那些模式,逐漸的加深對模式的理解,並把它變成自己的東西,能夠在其他的地方靈活的用起來。

2.轉錄 《易學設計模式·1.4 如何學習設計模式》郭志學 人民郵電出版社

如何學習設計模式
在瞭解了設計模式的歷史和分類後,應該如何學習設計模式呢?在學習設計模式之前,讀者一定要樹立一種意識,那就是:設計模式並不只是一種方法和技術,它更是一種思想、一個方法論。它和具體的語言沒有關係,學習設計模式最主要的目的就是要建立面向物件的思想,儘可能地面向介面程式設計、低耦合、高內聚,使你設計的程式儘可能地複用。【似是而非。學習設計模式能夠更好理解面向物件的思想,設計模式是一些設計的技巧和竅門,不要上升到思想、方法論好不好】
有些軟體開發人員,在程式設計時,總想著往某個設計模式上套,其實這樣是不對的,並沒有真正掌握設計模式的思想。其實很多時候讀者用了某種設計模式,只是自己不知道這個模式叫什麼名字而已。因此,在程式設計時,要根據自己的理解,使用合適的設計模式。
而有另外一些軟體開發人員,在程式設計時,動不動就給類起個類似模式的名字,比如叫某某Facade、某某Factory等,其實類裡面的內容和設計模式根本沒有一點關係,只是用來標榜自己懂設計模式而已。
因此,學習設計模式,首先要了解有哪些方面的設計模式可以供開發人員使用,然後再分別研究每個設計模式的原理,使用時機和方法,也就是說要在什麼情況下才使用某個設計模式,在瞭解某個設計模式的使用時機時,還要了解此時如果不使用這個設計模式,會造成什麼樣的後果。當對每個模式的原理和使用方法都瞭解了以後,更重要的是,學習面向物件的思想方式,在掌握面向物件的思想方式後,再回過頭來看設計模式,就會有更深刻的理解,最後,學習設計模式,一定要勤學多練。【就最後一句很贊同】

六、個人感悟

學習設計模式確實有幾種境界:

第一種是學習了一兩個設計模式,就一直想用到自己的程式碼中去;

第二種是學完全部設計模式,覺得很多模式都很相似,分不清楚它們之間有什麼區別;

第三種是靈活運用設計模式,就算不用具體哪種模式也可以設計也高質量的程式碼,無劍勝有劍。

最後附上總結圖:

Java設計模式之23種設計模式詳解

感謝:部落格園的chenssy Bobby0322 等博主,看了你們寫的部落格後受益匪淺,謝謝。

接下來,從10月份開始學習JDK & JAVA 知識提高。

到此這篇關於Java設計模式之23種設計模式詳解的文章就介紹到這了,更多相關Java 23種 設計模式內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!