當前位置:首頁 » 文件傳輸 » 設計模式中訪問者模式定義
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

設計模式中訪問者模式定義

發布時間: 2022-11-19 20:17:06

『壹』 設計模式(五)行為型模式

在上一篇結構型模式中,我們以功能為基本單位,研究了一些設計模式,用於實現功能轉換、功能組合、功能封裝等目的。

我們知道,面向對象編程有兩個核心元素:對象、對象間通信協作。從面向對象的角度看,任何系統和功能,都是由一個個對象,相互分工合作實現的。推而廣之,很多系統也都是這樣組織和運行的。

本章的設計模式,列舉了通用場景下常用功能機制的經典實現方法,講解了經典實現中是如何高效組織對象、控制對象協作交互的,具有很好的參考價值。

示例:https://www.runoob.com/design-pattern/chain-of-responsibility-pattern.html

責任鏈模式,就是把程序處理對象前後排列起來,形成一條處理線。處理線上需要被處理的信息,在處理線上向下傳遞,任何一個節點都可以隨時中斷傳遞。

GUI系統中的事件傳遞機制(在Javascript中叫做事件冒泡),是責任鏈模式最典型的應用之一。

當某一事件發生時,最頂層GUI對象會首先收到事件,但是它先不處理,而是依次交給命中的子GUI對象處理。當子GUI對象返回為False時,表示事件未被接收,此時父GUI對象才真正對發生的事件進行業務處理。

可以看出,事件傳遞機制,是一種增強版的責任鏈模式,它的節點處理權,經歷了向下和向上的雙向傳遞過程。

總結:當項目中一個數據對象,需要被多個處理對象進行處理時,可以將處理對象鏈接起來,然後把數據對象傳遞給頭節點,隨著處理的進行,數據對象的處理權會在處理鏈中流動,從而完成整個處理過程。

責任鏈模式結構適用於需求固定的場景,用於實現簡單高效的處理機制。假如需求不斷變化,而且功能很復雜,那麼用責任鏈模式很可能就無法勝任了,需要採用新的高復雜度的設計。例如,如果想要數據對象在所有處理對象中根據狀態來實現跳轉,可以選擇使用狀態機等其他方案來實現。

示例:https://www.runoob.com/design-pattern/command-pattern.html

想要實現撤銷、重做、事務等功能,可以使用此設計模式。通常在編輯器、資料庫中有此類功能需求。

命令也就是請求,或者叫調用。命令模式要求將請求參數和請求相關的方法封裝在一起。

請求對象中封裝了實現「撤銷」、「重做」、「事務」功能所需要的所有信息,實現了關聯信息的高內聚,所以可以實現我們想要的功能。

例如,可以在請求對象中保存修改之前的值、修改之後的值。利用修改之前的值,可以實現「撤銷」功能;利用修改之後的值,可以實現「重做」功能。如果將所有請求對象都記錄下來,並按照先後順序排列起來,形成「撤銷重做」堆棧,這樣就可以實現連續的「撤銷」、「重做」。「事務」則是「撤銷」與「重做」的結合體,正常執行流程等同於「重做」,發生錯誤需要回滾,等同於「撤銷」。

如果不採用這種方式,會導致實現這些功能的信息,分散在源碼中多個地方,或者已經丟失,沒有保存,就無法實現「撤銷」、「重做」、「事務」功能。

同時,實現請求參數高內聚,也可以很方便地將它們保存到磁碟上,保存到文件的過程叫做「序列化」,從文件中讀取的過程叫「反序列化」。這里的序列指的就是二進制流。

Qt中與命令模式相關的部分是:Undo Framework,裡面有示例項目,不熟悉的同學可以抽點時間看一看。

示例:https://www.runoob.com/design-pattern/interpreter-pattern.html

顧名思義,解釋器模式是用來實現解釋器的。 解釋器是這樣一個程序:解釋器以符合語法的文本為輸入,解釋輸入內容,完成一定的計算功能。文本可以在程序運行時動態載入,動態解釋、動態執行。

實現簡單的解釋器:命令行程序,如ping命令、cd命令等; 實現復雜的解釋器:腳本語言解釋器,如python,lua,javascript;計算器。

我們知道,在GUI圖形用戶界面被發明之前,人類和程序之間的交互是通過敲命令行實現的,缺點是使用難度較大,門檻較高。 在GUI發明以後,交互更加友好,電腦更加易於使用了,所以也更加普及了。

但是GUI交互的缺點在於,不夠靈活,對參數的控制粒度不夠細致。例如,現在大多數開發者都使用集成開發環境來開發軟體,一般情況下都使用默認參數,比較方便。但是如果你想要更改某些編譯選項,可能還是需要直接修改底層的編譯命令。命令相對於GUI元素更加靈活,過於靈活的地方用GUI比較難於實現,例如組合、遞歸、跳轉等等。在這些場景下,使用解釋器是非常合適的。但是通常情況下,這個模式並不常用。

示例:https://www.runoob.com/design-pattern/iterator-pattern.html

在需要多次遍歷同一個數據集合的時候,為了少些一些for,或者想要把遍歷過程封裝起來,降低耦合,就可以使用迭代器模式。這個模式非常常用。

迭代器就是一個專門用來遍歷數組的類。它只需要實現兩個介面:hasNext()、next()。 hasNext()介面用於控制循環何時停止;next()介面用於取出當前位置的數據元素,並將遍歷指針指向下一個元素。 當然,構造迭代器對象的時候,需要將數據集合傳遞給迭代器,讓迭代器知道要遍歷哪些數據。

原本需要用for循環來遍歷的代碼,現在通過封裝,提取出了「遍歷」這一功能所需要的必要信息,定義了兩個介面,把不必要暴露的信息封裝在了迭代器中,妥妥的實現了解耦。

示例:https://www.runoob.com/design-pattern/mediator-pattern.html

中介者模式是指,在原本直接通信的對象之間,添加一個通信中間層,使對象間通信變為間接通信,降低對象間的耦合。

此模式和代理模式基本思想上是一致的。二者的區別是:代理模式是通過加一個中間層,來實現兩個原本很難交互的功能主體,實現順暢交互;中介者模式是為了降低對象間通信時的耦合而提出的,為的是提高代碼的可維護性。

比較大的項目中會用到,一般存在於某些框架中。因為大的項目中對象繁多,通信也比較復雜,適合使用中介者模式。

在大的項目中,一般會有一個全局的通信管理器,任何對象都可以使用通信管理器提供的介面,將自己注冊為某一個具有唯一ID消息的發送者和接收者。這樣發送者只需要發送消息,不需要管誰來接收,不需要擁有發送者的實例指針,發出消息後,已注冊的接收者都會收到消息。接收者不需要管信號是誰發的,即不需要擁有發送者的實例指針。

所以,中介者模式也可以叫「通信中介模式」。

示例:https://www.runoob.com/design-pattern/memento-pattern.html

這個模式和狀態存檔功能是綁定在一起的。為了在程序中實現狀態存檔功能,可以使用備忘錄模式。

原例子中有三個類,個人覺得沒有必要,這里我們簡化成兩個類,即備忘錄模式中有兩個類:狀態對象類和狀態對象管理類。 狀態對象類是狀態欄位是集合,並提供了存取介面;狀態對象管理類負責組織和保存狀態對象。當然實際實現中可以根據需求增加類,配合使用,完成狀態保存恢復。

當一個對象會影響到其他多個對象時,即當對象間存在一對多關系時,使用觀察者模式。 一般應用於單向通知的場景,如GUI中滑鼠事件、按鍵事件、窗口事件通知。使用Qt中的信號槽機制可以實現此模式。

「一」是指發生變化的那個對象,「多」是指需要獲取此變化通知的對象組。其中,變化消息是單向地由「一」到「多」傳遞的。如果不是單向的或者對象間不是一對多的關系,更加復雜,就需要重新思考其他對象間通信模型。

如果不使用此模式,可能會導致觀察者不能動態增加或刪除;可能會造成發送者的業務代碼和接收者的響應代碼混在一起,耦合嚴重。

使用此模式,需要為觀察者設計一個基類,並設計一個接收通知的介面,所有觀察者需要實現通知介面;所有觀察者指針可以保存在隊列中,實現動態增刪。

狀態模式用於實現狀態機。 如果一個程序功能中存在某些狀態,在一定情況下,這些狀態可以互相轉換,並且在轉換前後需要作出對應的操作,這種情況下使用狀態機來實現就非常合適。

如果不使用狀態機(狀態模式),一般的實現方法是使用一連串的if-else,或者使用長長的switch-case來實現。這樣做的缺點,一方面狀態判斷不夠高效,另一方面是業務代碼集中在一塊,不好維護。

使用狀態機,每個狀態都是一個類,相關的業務代碼分布到各自的狀態類中,能夠實現不同的狀態及與狀態相關的業務代碼解耦。同時某個狀態和下一個狀態是關聯好的,在狀態切換時,效率更高,不需要執行長長的判斷。

Qt中已實現狀態機框架,The State Machine Framework,在此框架下,我們可以更加專注於業務實現,而不是狀態機本身的技術細節。

示例:https://www.runoob.com/design-pattern/null-object-pattern.html

使用基類保存子類對象通常有兩種做法:

第一種方法用指針是基本方法,但是指針用起來要非常小心,要考慮內存釋放的問題。此時空對象就可以用空指針表示。 第二種方法用基類對象保存子類對象,這種方法使用起來相對省心,不用與指針打交道,使用者不用直接管理內存。例如Qt中的Qt XML C++ Classes類的設計就是採用這種方式設計的。這種情況下,因為不使用指針,就需要使用空對象來代替空指針。

可以仿造Qt XML中的類進行設計。一般需要提供isNull()介面,對象類型轉換介面等。

策略模式和橋接模式類似,用於實現功能切換與組合。二者區別在於,策略模式專注於一個功能的不同實現方式;橋接模式專注於多個功能之間的組合。

將功能抽象成單獨的類,功能切換只需要切換不同的功能子類即可,同一個功能需要實現同一個功能介面。

示例:https://www.runoob.com/design-pattern/template-pattern.html

模板模式應該是我們最熟悉的。 這里的模板就是介面類,介面類定義了使用者和功能提供者之間交互的函數列表。子類負責功能的具體實現。

示例:https://www.runoob.com/design-pattern/visitor-pattern.html

訪問者模式用於將數據結構與數據操作相分離。

訪問者模式和迭代器模式類似。迭代器模式一般用來遍歷數組,所以沒有把for封裝起來。而訪問者模式可以遍歷一切類型的數據結構,具體的遍歷過程被封裝在接收者內部。同時,對每一個遍歷得到的數組元素的操作,被封裝在訪問者內部。每一種對元素不同的操作,都需要新建一個訪問者類。

接收者需要實現accept()介面,訪問者需要實現visit()介面。

每種設計模式都有使用場景,都有優點和缺點。隨著需求的改變,任何一種設計模式可能都將不再適用。

『貳』 各位,23種設計模式都在哪些場合運用到

其中創建型有:
一、Singleton,單例模式:保證一個類只有一個實例,並提供一個訪問它的全局訪問點
例如:隨處可見,比如Servlet,sprigMVC創建時都是單例多線程的。
完美的實例是:private static Singleton instance = new Singleton();
創建線程的方式有很多種,但是很多都扛不住多線程的檢驗,上面是簡單又實用的例子,多線程下也是安全的。

二、Abstract Factory,抽象工廠:提供一個創建一系列相關或相互依賴對象的介面,而無須指定它們的具體類。

三、Factory Method,工廠方法:定義一個用於創建對象的介面,讓子類決定實例化哪一個類,Factory Method使一個類的實例化延遲到了子類。
例如:雖然簡單工廠(靜態工廠)沒有進入23種設計模式,但是java web中的很多配置文件玩的還是它。
Spring中下面三種方式實例化bean:
1.使用類構造器實例化
<bean id="orderService" class="cn.itcast.OrderServiceBean"/>
2.使用靜態工廠方法實例化
<bean id="personService" class="cn.itcast.service.OrderFactory" factory- method="createOrder"/>
public class OrderFactory {
public static OrderServiceBean createOrder(){
return new OrderServiceBean();
}
}
3.使用實例工廠方法實例化:
<bean id="personServiceFactory" class="cn.itcast.service.OrderFactory"/>
<bean id="personService" factory-bean="personServiceFactory" factory-method="createOrder"/>
public class OrderFactory {
public OrderServiceBean createOrder(){
return new OrderServiceBean();
}
}
第一種方法,IOC容易直接根據配置文件中的class屬性通過反射創建一個實例,使用的是該類的默認構造方法。第二種則是調用class指定的工廠類的
工廠方法,來返回一個相應的bean實例,值得注意的是工廠類的方法是靜態方法,所以不用產生工廠本身的實例。而第三種則不同,它除了配置與第二種相同
外,唯一的不同就是方法不是靜態的,所以創建bean的實例對象時需要先生成工廠類的實例。實例了bean對象時,需要對其中的屬性也進行賦值,這時就是經常被提及的依賴注入。
以上其實有錯誤:Spring很多情況下創建對象很定是反射呀,尤其是註解和DI(依賴注入),小朋友,想什麼呢?肯定不是用new()來創建:
Class c = Class.forName("cn.itcast.OrderServiceBean");
Object bean = c.newInstance();

四、Builder,建造模式:將一個復雜對象的構建與他的表示相分離,使得同樣的構建過程可以創建不同的表示。

五、Prototype,原型模式:用原型實例指定創建對象的種類,並且通過拷貝這些原型來創建新的對象。

行為型有:
六、Iterator,迭代器模式:提供一個方法順序訪問一個聚合對象的各個元素,而又不需要暴露該對象的內部表示。
例如:jdk中的各種容器類的基礎模式

七、Observer,觀察者模式:定義對象間一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知自動更新。
例如:據說是jdk使用最多的模式,好比郵件訂閱或RSS訂閱

八、Template Method,模板方法:定義一個操作中的演算法的骨架,而將一些步驟延遲到子類中,TemplateMethod使得子類可以不改變一個演算法的結構即可以重定義該演算法得某些特定步驟。

九、Command,命令模式:將一個請求封裝為一個對象,從而使你可以用不同的請求對客戶進行參數化,對請求排隊和記錄請求日誌,以及支持可撤銷的操作。

十、State,狀態模式:允許對象在其內部狀態改變時改變他的行為。對象看起來似乎改變了他的類。

十一、Strategy,策略模式:定義一系列的演算法,把他們一個個封裝起來,並使他們可以互相替換,本模式使得演算法可以獨立於使用它們的客戶。
例如:comparator 比較器的實現利用了此模式

十二、China of Responsibility,職責鏈模式:使多個對象都有機會處理請求,從而避免請求的送發者和接收者之間的耦合關系 。
此處強調一點就是,鏈接上的請求可以是一條鏈,可以是一個樹,還可以是一個環,模式本身不約束這個,需要我們自己去實現,同時,在一個時刻,命令只允許由一個對象傳給另一個對象,而不允許傳給多個對象
例如:struts2 interceptor 用到的就是是責任鏈模式

十三、Mediator,中介者模式:用一個中介對象封裝一些列的對象交互。

十四、Visitor,訪問者模式:表示一個作用於某對象結構中的各元素的操作,它使你可以在不改變各元素類的前提下定義作用於這個元素的新操作。

十五、Interpreter,解釋器模式:給定一個語言,定義他的文法的一個表示,並定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。

十六、Memento,備忘錄模式:在不破壞對象的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態。

結構型有:
十七、Composite,組合模式:將對象組合成樹形結構以表示部分整體的關系,Composite使得用戶對單個對象和組合對象的使用具有一致性。

十八、Facade,外觀模式:為子系統中的一組介面提供一致的界面,facade提供了一高層介面,這個介面使得子系統更容易使用。

十九、Proxy,代理模式:為其他對象提供一種代理以控制對這個對象的訪問。
例如:經典的體現在Spring AOP切面中,Spring中利用了倆種代理類型。
其實,代理也分為靜態和動態,但是我們一般常用動態,因為靜態代理秀不起來

二十、Adapter,適配器模式:將一類的介面轉換成客戶希望的另外一個介面,Adapter模式使得原本由於介面不兼容而不能一起工作那些類可以一起工作。
其中對象的適配器模式是各種結構型模式的起源,分為三種:類,對象,介面的適配器模式。
結一下三種適配器模式的應用場景:
類的適配器模式:當希望將一個類轉換成滿足另一個新介面的類時,可以使用類的適配器模式,創建一個新類,繼承原有的類,實現新的介面即可。
對象的適配器模式:當希望將一個對象轉換成滿足另一個新介面的對象時,可以創建一個Wrapper類,持有原類的一個實例,在Wrapper類的方法中,調用實例的方法就行。
介面的適配器模式:當不希望實現一個介面中所有的方法時,可以創建一個抽象類Wrapper,實現所有方法,我們寫別的類的時候,繼承抽象類即可。
例如:java io流中大量使用

二十一、Decrator,裝飾模式:動態地給一個對象增加一些額外的職責,就增加的功能來說,Decorator模式相比生成子類更加靈活。
對比:適配器模式主要是為了介面的轉換,而裝飾者模式關注的是通過組合來動態的為被裝飾者注入新的功能或行為(即所謂的責任)。

二十二、Bridge,橋模式:將抽象部分與它的實現部分相分離,使他們可以獨立的變化。

二十三、Flyweight,享元模式:主要目的是實現對象的共享,即共享池,當系統中對象多的時候可以減少內存的開銷,通常與工廠模式一起使用。
例如:資料庫連接池便是這個原理

『叄』 軟體設計模式主要有哪幾種

軟體設計模式主要有以下三大類共23種:

一、創建型模式:

1、工廠方法模式工廠方法模式的創建是因為簡單工廠模式有一個問題,在簡單工廠模式中類的創建依賴工廠類,如果想要拓展程序,必須對工廠類進行修改,這違背了開閉原則,所以就出現了工廠方法模式,只需要創建一個工廠介面和多個工廠實現類。

2、抽象工廠模式抽象工廠模式是提供一個創建一系列相關或相互依賴對象的介面,而無需指定它們具體的類。區別於工廠方法模式的地方,工廠方法模式是創建一個工廠,可以實現多種對象;而抽象工廠模式是提供一個抽象工廠介面,裡面定義多種工廠,每個工廠可以生產多種對象。

3、單例模式單例模式能保證一個類僅有一個實例,並提供一個訪問它的全局訪問點,同時在類內部創造單一對象,通過設置許可權,使類外部無法再創造對象。單例對象能保證在一個JVM中,該對象只有一個實例存在。

4、建造者模式建造者模式是將一個復雜的構建與其表示相分離,使得同樣的構建過程可以創建不同的表示。在程序當中就是將一些不會變的基本組件,通過builder來進行組合,構建復雜對象,實現分離。

5、原型模式:原型模式是用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。其實就是將對象復制了一份並返還給調用者,對象需繼承Cloneable並重寫clone方法。原型模式的思想就是將一個對象作為原型,對其進行復制、克隆,產生一個和原對象類似的新對象。

二、結構型模式:

1、適配器模式適配器模式是使得原本由於介面不兼容而不能一起工作的那些類可以一起工作,銜接兩個不兼容、獨立的介面的功能,使得它們能夠一起工作,適配器起到中介的作用。

2、裝飾模式:裝飾器模式是動態地給一個對象添加一些額外的職責,給一個對象增加一些新的功能,要求裝飾對象和被裝飾對象實現同一個介面,裝飾對象持有被裝飾對象的實例。除了動態的增加,也可以動態的撤銷,要做到動態的形式,不可以用繼承實現,因為繼承是靜態的。

3、代理模式代理模式是為其他對象提供一種代理以控制對這個對象的訪問,也就是創建類的代理類,間接訪問被代理類的過程中,對其功能加以控制。

4、外觀模式外觀模式是為子系統中的一組介面提供一個一致的界面,外觀模式定義了一個高層介面,這個介面使得這一子系統更加容易使用。

5、橋接模式橋接模式是將抽象部分與實現部分分離,使它們都可以獨立的變化。橋接模式就是把事物和其具體實現分開,使他們可以各自獨立的變化(突然聯想到了mvc模式)。

6、組合模式:組合模式是將對象組合成樹形結構以表示"部分-整體"的層次結構,組合模式使得用戶對單個對象和組合對象的使用具有一致性。

7、享元模式:享元模式是運用共享技術有效地支持大量細粒度的對象。享元模式的主要目的是實現對象的共享,即共享池,當系統中對象多的時候可以減少內存的開銷,重用現有的同類對象,若未找到匹配的對象,則創建新對象,這樣可以減少對象的創建,降低系統內存,提高效率。

三、行為型模式:

1、策略模式:

策略模式是定義一系列的演算法,把它們一個個封裝起來, 並且使它們可相互替換,且演算法的變化不會影響到使用演算法的客戶。

2、模版方法模式:

模板方法模式是定義一個操作中的演算法的骨架,而將一些步驟延遲到子類中。該模式就是在一個抽象類中,有一個主方法,再定義1...n個方法,可以是抽象的,也可以是實際的方法,定義一個類,繼承該抽象類,重寫抽象方法,通過調用抽象類,實現對子類的調用。

模板方法使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟,將一些固定步驟、固定邏輯的方法封裝成模板方法。調用模板方法即可完成那些特定的步驟。

3、觀察者模式:

觀察者模式是定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並被自動更新。

也就是當被觀察者狀態變化時,通知所有觀察者,這種依賴方式具有雙向性,在QQ郵箱中的郵件訂閱和RSS訂閱,當用戶瀏覽一些博客時,經常會看到RSS圖標,簡單來說就是當訂閱了該文章,如果後續有更新,會及時通知用戶。這種現象即是典型的觀察者模式。

4、迭代器模式:

迭代器模式是提供一種方法順序訪問一個聚合對象中各個元素, 而又無須暴露該對象的內部表示。

在Java當中,將聚合類中遍歷各個元素的行為分離出來,封裝成迭代器,讓迭代器來處理遍歷的任務;使簡化聚合類,同時又不暴露聚合類的內部,在我們經常使用的JDK中各個類也都是這些基本的東西。

5、責任鏈模式:

責任鏈模式是避免請求發送者與接收者耦合在一起,讓多個對象都有可能接收請求,將這些對象連接成一條鏈,並且沿著這條鏈傳遞請求,直到有對象處理它為止。有多個對象,每個對象持有對下一個對象的引用,這樣就會形成一條鏈,請求在這條鏈上傳遞,直到某一對象決定處理該請求。

6、命令模式:

命令模式是將一個請求封裝成一個對象,從而使發出者可以用不同的請求對客戶進行參數化。模式當中存在調用者、接收者、命令三個對象,實現請求和執行分開;調用者選擇命令發布,命令指定接收者。

7、備忘錄模式:

備忘錄模式是在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態。創建一個備忘錄類,用來存儲原始類的信息;同時創建備忘錄倉庫類,用來存儲備忘錄類,主要目的是保存一個對象的某個狀態,以便在適當的時候恢復對象,也就是做個備份。

8、狀態模式:

狀態模式是允許對象在內部狀態發生改變時改變它的行為。對象具有多種狀態,且每種狀態具有特定的行為。

9、訪問者模式:

訪問者模式主要是將數據結構與數據操作分離。在被訪問的類裡面加一個對外提供接待訪問者的介面,訪問者封裝了對被訪問者結構的一些雜亂操作,解耦結構與演算法,同時具有優秀的擴展性。通俗來講就是一種分離對象數據結構與行為的方法。

10、中介者模式:

中介者模式是用一個中介對象來封裝一系列的對象交互,中介者使各對象不需要顯式地相互引用,從而使其耦合鬆散,而且可以獨立地改變它們之間的交互。

11、解釋器模式:

解釋器模式是給定一個語言,定義它的文法表示,並定義一個解釋器,這個解釋器使用該標識來解釋語言中的句子,基本也就用在這個范圍內,適用面較窄,例如:正則表達式的解釋等。


(3)設計模式中訪問者模式定義擴展閱讀:

軟體設計的概念以及意義:

軟體設計模式是對軟體設計經驗的總結,是對軟體設計中反復出現的設計問題的成功解決方案的描述。為了記錄這些成功的設計經驗並方便以後使用,軟體設計模式通常包含 4 個基本要素:模式名稱、問題、解決方案以及效果。

模式名稱實際上就是一個幫助記憶的名稱,是用於軟體設計的技術術語,有助於設計者之間的交流。

問題描述了設計者所面臨的設計場景,用於告訴設計者在什麼情況下使用該模式。

解決方案描述了設計的細節,通常會給出方案的原理圖示(例如 UML 的類圖,序列圖等,也可能是一些示意圖)及相關文字說明,如果可能,還會給出一些代碼實例,以便對解決方案的深入理解。

效果描述了設計方案的優勢和劣勢,這些效果通常面向軟體的質量屬性,例如,可擴展性、可復用性等。

軟體設計模式的重要意義在於設計復用。設計模式可以使設計者更加方便地借鑒或直接使用已經過證實的成功設計方案,而不必花費時間進行重復設計。一些設計模式甚至提供了顯示的類圖設計及代碼實例,為設計的文檔化及軟體的開發提供了直接的支持。

『肆』 設計模式有哪些

總體來說設計模式分為三大類:一、創建型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。二、結構型模式,共七種:適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。三、行為型模式,共十一種:策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、解釋器模式。1、工廠方法模式:定義一個用於創建對象的介面,讓子類決定實例化哪一個類。Factory Method 使一個類的實例化延遲到其子類。工廠模式有一個問題就是,類的創建依賴工廠類,也就是說,如果想要拓展程序,必須對工廠類進行修改,這違背了閉包原則,所以,從設計角度考慮,有一定的問題,這就用到工廠方法模式。創建一個工廠介面和創建多個工廠實現類,這樣一旦需要增加新的功能,直接增加新的工廠類就可以了,不需要修改之前的代碼。2、抽象工廠模式:提供一個創建一系列相關或相互依賴對象的介面,而無需指定它們具體的類。抽象工廠需要創建一些列產品,著重點在於"創建哪些"產品上,也就是說,如果你開發,你的主要任務是劃分不同差異的產品線,並且盡量保持每條產品線介面一致,從而可以從同一個抽象工廠繼承。3、單例模式:單例對象(Singleton)是一種常用的設計模式。在Java應用中,單例對象能保證在一個JVM中,該對象只有一個實例存在。

『伍』 設計模式的設計原則

為什麼要提倡「Design Pattern呢?根本原因是為了代碼復用,增加可維護性。那麼怎麼才能實現代碼復用呢?面向對象有幾個原則:單一職責原則 (Single Responsiblity Principle SRP)開閉原則(Open Closed Principle,OCP)、里氏代換原則(Liskov Substitution Principle,LSP)、依賴倒轉原則(Dependency Inversion Principle,DIP)、介面隔離原則(Interface Segregation Principle,ISP)、合成/聚合復用原則(Composite/Aggregate Reuse Principle,CARP)、最小知識原則(Principle of Least Knowledge,PLK,也叫迪米特法則)。開閉原則具有理想主義的色彩,它是面向對象設計的終極目標。其他幾條,則可以看做是開閉原則的實現方法。
設計模式就是實現了這些原則,從而達到了代碼復用、增加可維護性的目的。 此原則是由Bertrand Meyer提出的。原文是:「Software entities should be open for extension,but closed for modification」。就是說模塊應對擴展開放,而對修改關閉。模塊應盡量在不修改原(是「原」,指原來的代碼)代碼的情況下進行擴展。那麼怎麼擴展呢?我們看工廠模式「factory pattern」:假設中關村有一個賣盜版盤和毛片的小子,我們給他設計一「光碟銷售管理軟體」。我們應該先設計一「光碟」介面。如圖:
[pre]
______________
|<>|
| 光碟 |
|_____________|
|+賣() |
| |
|_____________|
[/pre]
而盜版盤和毛片是其子類。小子通過「DiscFactory」來管理這些光碟。代碼為: publicclassDiscFactory{publicstatic光碟getDisc(Stringname){return(光碟)Class.forName(name).newInstance();}}有人要買盜版盤,怎麼實現呢? publicclass小子{publicstaticvoidmain(String[]args){光碟d=DiscFactory.getDisc(盜版盤);d.賣();}}如果有一天,這小子良心發現了,開始賣正版軟體。沒關系,我們只要再創建一個「光碟」的子類「正版軟體」就可以了,不需要修改原結構和代碼。怎麼樣?對擴展開放,對修改關閉——「開閉原則」。
工廠模式是對具體產品進行擴展,有的項目可能需要更多的擴展性,要對這個「工廠」也進行擴展,那就成了「抽象工廠模式」。 合成/聚合復用原則(Composite/Aggregate Reuse Principle,CARP)經常又叫做合成復用原則。合成/聚合復用原則就是在一個新的對象裡面使用一些已有的對象,使之成為新對象的一部分;新的對象通過向這些對象的委派達到復用已有功能的目的。它的設計原則是:要盡量使用合成/聚合,盡量不要使用繼承。
就是說要少用繼承,多用合成關系來實現。我曾經這樣寫過程序:有幾個類要與資料庫打交道,就寫了一個資料庫操作的類,然後別的跟資料庫打交道的類都繼承這個。結果後來,我修改了資料庫操作類的一個方法,各個類都需要改動。「牽一發而動全身」!面向對象是要把波動限制在盡量小的范圍。
在Java中,應盡量針對Interface編程,而非實現類。這樣,更換子類不會影響調用它方法的代碼。要讓各個類盡可能少的跟別人聯系,「不要與陌生人說話」。這樣,城門失火,才不至於殃及池魚。擴展性和維護性才能提高。 設計模式分為三種類型,共23種。 創建型模式:單例模式、抽象工廠模式、建造者模式、工廠模式、原型模式。 結構型模式:適配器模式、橋接模式、裝飾模式、組合模式、外觀模式、享元模式、代理模式。 行為型模式:模版方法模式、命令模式、迭代器模式、觀察者模式、中介者模式、備忘錄模式、解釋器模式(Interpreter模式)、狀態模式、策略模式、職責鏈模式(責任鏈模式)、訪問者模式。 按字典序排列簡介如下。
Abstract Factory(抽象工廠模式):提供一個創建一系列相關或相互依賴對象的介面,而無需指定它們具體的類。
Adapter(適配器模式):將一個類的介面轉換成客戶希望的另外一個介面。Adapter模式使得原本由於介面不兼容而不能一起工作的那些類可以一起工作。
Bridge(橋接模式):將抽象部分與它的實現部分分離,使它們都可以獨立地變化。
Builder(建造者模式):將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。
Chain of Responsibility(責任鏈模式):為解除請求的發送者和接收者之間耦合,而使多個對象都有機會處理這個請求。將這些對象連成一條鏈,並沿著這條鏈傳遞該請求,直到有一個對象處理它。
Command(命令模式):將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支持可取消的操作。
Composite(組合模式):將對象組合成樹形結構以表示「部分-整體」的層次結構。它使得客戶對單個對象和復合對象的使用具有一致性。
Decorator(裝飾模式):動態地給一個對象添加一些額外的職責。就擴展功能而言, 它比生成子類方式更為靈活。
Facade(外觀模式):為子系統中的一組介面提供一個一致的界面,Facade模式定義了一個高層介面,這個介面使得這一子系統更加容易使用。
Factory Method(工廠模式):定義一個用於創建對象的介面,讓子類決定將哪一個類實例化。Factory Method使一個類的實例化延遲到其子類。
Flyweight(享元模式):運用共享技術有效地支持大量細粒度的對象。
Interpreter(解析器模式):給定一個語言, 定義它的文法的一種表示,並定義一個解釋器, 該解釋器使用該表示來解釋語言中的句子。
Iterator(迭代器模式):提供一種方法順序訪問一個聚合對象中各個元素,而又不需暴露該對象的內部表示。
Mediator(中介模式):用一個中介對象來封裝一系列的對象交互。中介者使各對象不需要顯式地相互引用,從而使其耦合鬆散,而且可以獨立地改變它們之間的交互。
Memento(備忘錄模式):在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態。這樣以後就可將該對象恢復到保存的狀態。
Observer(觀察者模式):定義對象間的一種一對多的依賴關系,以便當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並自動刷新。
Prototype(原型模式):用原型實例指定創建對象的種類,並且通過拷貝這個原型來創建新的對象。
Proxy(代理模式):為其他對象提供一個代理以控制對這個對象的訪問。
Singleton(單例模式):保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。 單例模式是最簡單的設計模式之一,但是對於Java的開發者來說,它卻有很多缺陷。在九月的專欄中,David Geary探討了單例模式以及在面對多線程(multi-threading)、類裝載器(class loaders)和序列化(serialization)時如何處理這些缺陷。
State(狀態模式):允許一個對象在其內部狀態改變時改變它的行為。對象看起來似乎修改了它所屬的類。
Strategy(策略模式):定義一系列的演算法,把它們一個個封裝起來, 並且使它們可相互替換。本模式使得演算法的變化可獨立於使用它的客戶。
Template Method(模板方法模式):定義一個操作中的演算法的骨架,而將一些步驟延遲到子類中。Template Method使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。
Visitor(訪問者模式):表示一個作用於某對象結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用於這些元素的新操作。
從下一節開始,詳細描述以下每一種設計模式。 意圖
定義一個用於創建對象的介面,讓子類決定實例化哪一個類。Factory Method 使一個類的實例化延遲到其子類。
適用性 當一個類不知道它所必須創建的對象的類的時候。 當一個類希望由它的子類來指定它所創建的對象的時候。 當類將創建對象的職責委託給多個幫助子類中的某一個,並且你希望將哪一個幫助子類是代理者這一信息局部化的時候。 意圖
提供一個創建一系列相關或相互依賴對象的介面,而無需指定它們具體的類。
適用性 一個系統要獨立於它的產品的創建、組合和表示時。 一個系統要由多個產品系列中的一個來配置時。 當你要強調一系列相關的產品對象的設計以便進行聯合使用時。 當你提供一個產品類庫,而只想顯示它們的介面而不是實現時。 意圖
將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。
適用性 當創建復雜對象的演算法應該獨立於該對象的組成部分以及它們的裝配方式時。 當構造過程必須允許被構造的對象有不同的表示時。 意圖
用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。
適用性 當要實例化的類是在運行時刻指定時,例如,通過動態裝載;或者 為了避免創建一個與產品類層次平行的工廠類層次時;或者 當一個類的實例只能有幾個不同狀態組合中的一種時。建立相應數目的原型並克隆它們可能比每次用合適的狀態手工實例化該類更方便一些。 意圖
保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。
適用性 當類只能有一個實例而且客戶可以從一個眾所周知的訪問點訪問它時。 當這個唯一實例應該是通過子類化可擴展的,並且客戶應該無需更改代碼就能使用一個擴展的實例時。 意圖
將一個類的介面轉換成另外一個客戶希望的介面。Adapter 模式使得原本由於介面不兼容而不能一起工作的那些類可以一起工作。
適用性 你想使用一個已經存在的類,而它的介面不符合你的需求。 你想創建一個可以復用的類,該類可以與其他不相關的類或不可預見的類(即那些介面可能不一定兼容的類)協同工作。 (僅適用於對象Adapter)你想使用一些已經存在的子類,但是不可能對每一個都進行子類化以匹配它們的介面。對象適配器可以適配它的父類介面。 意圖
將抽象部分與它的實現部分分離,使它們都可以獨立地變化。
適用性 你不希望在抽象和它的實現部分之間有一個固定的綁定關系。例如這種情況可能是因為,在程序運行時刻實現部分應可以被選擇或者切換。 類的抽象以及它的實現都應該可以通過生成子類的方法加以擴充。這時B r i d g e 模式使你可以對不同的抽象介面和實現部分進行組合,並分別對它們進行擴充。 對一個抽象的實現部分的修改應對客戶不產生影響,即客戶的代碼不必重新編譯。 (C++)你想對客戶完全隱藏抽象的實現部分。在C++中,類的表示在類介面中是可見的。 有許多類要生成。這樣一種類層次結構說明你必須將一個對象分解成兩個部分。Rumbaugh稱這種類層次結構為「嵌套的普化」(nested generalizations )。 你想在多個對象間共享實現(可能使用引用計數),但同時要求客戶並不知道這一點。一個簡單的例子便是Coplien的String類,在這個類中多個對象可以共享同一個字元串表示(StringRep)。 意圖
將對象組合成樹形結構以表示「部分-整體」的層次結構。C o m p o s i t e 使得用戶對單個對象和組合對象的使用具有一致性。
適用性 你想表示對象的部分—整體層次結構。 你希望用戶忽略組合對象與單個對象的不同,用戶將統一地使用組合結構中的所有對象。 意圖
動態地給一個對象添加一些額外的職責。就增加功能來說,Decorator模式相比生成子類更為靈活。
適用性 在不影響其他對象的情況下,以動態、透明的方式給單個對象添加職責。 處理那些可以撤消的職責。 當不能採用生成子類的方法進行擴充時。一種情況是,可能有大量獨立的擴展,為支持每一種組合將產生大量的子類,使得子類數目呈爆炸性增長。另一種情況可能是因為類定義被隱藏,或類定義不能用於生成子類。 意圖
為子系統中的一組介面提供一個一致的界面,Facade模式定義了一個高層介面,這個介面使得這一子系統更加容易使用。
適用性 當你要為一個復雜子系統提供一個簡單介面時。子系統往往因為不斷演化而變得越來越復雜。大多數模式使用時都會產生更多更小的類。這使得子系統更具可重用性,也更容易對子系統進行定製,但這也給那些不需要定製子系統的用戶帶來一些使用上的困難。Facade可以提供一個簡單的預設視圖,這一視圖對大多數用戶來說已經足夠,而那些需要更多的可定製性的用戶可以越過Facade層。 客戶程序與抽象類的實現部分之間存在著很大的依賴性。引入Facade將這個子系統與客戶以及其他的子系統分離,可以提高子系統的獨立性和可移植性。 當你需要構建一個層次結構的子系統時,使用門面模式定義子系統中每層的入口點。如果子系統之間是相互依賴的,你可以讓它們僅通過Facade進行通訊,從而簡化了它們之間的依賴關系。 意圖
運用共享技術有效地支持大量細粒度的對象。
適用性 一個應用程序使用了大量的對象。 完全由於使用大量的對象,造成很大的存儲開銷。 對象的大多數狀態都可變為外部狀態。 如果刪除對象的外部狀態,那麼可以用相對較少的共享對象取代很多組對象。 應用程序不依賴於對象標識。由於Flyweight對象可以被共享,對於概念上明顯有別的對象,標識測試將返回真值。 意圖
為其他對象提供一種代理以控制對這個對象的訪問。
適用性
在需要用比較通用和復雜的對象指針代替簡單的指針的時候,使用Proxy模式。下面是一 些可以使用Proxy模式常見情況: 遠程代理(Remote Proxy)為一個對象在不同的地址空間提供局部代表。 虛代理(Virtual Proxy)根據需要創建開銷很大的對象。 保護代理(Protection Proxy)控制對原始對象的訪問。保護代理用於對象應該有不同 的訪問許可權的時候。 智能指引(Smart Reference)取代了簡單的指針,它在訪問對象時執行一些附加操作。 它的典型用途包括: 對指向實際對象的引用計數,這樣當該對象沒有引用時,可以自動釋放它(也稱為SmartPointers)。 當第一次引用一個持久對象時,將它裝入內存。 在訪問一個實際對象前,檢查是否已經鎖定了它,以確保其他對象不能改變它。 意圖
使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關系。將這些對象連成一條鏈,並沿著這條鏈傳遞該請求,直到有一個對象處理它為止。
適用性 有多個的對象可以處理一個請求,哪個對象處理該請求運行時刻自動確定。 你想在不明確指定接收者的情況下,向多個對象中的一個提交一個請求。 可處理一個請求的對象集合應被動態指定。 意圖
將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支持可取消的操作
適用性 像上面討論的MenuItem對象那樣,抽象出待執行的動作以參數化某對象。你可用過程語言中的回調(callback)函數表達這種參數化機制。所謂回調函數是指函數先在某處注冊,而它將在稍後某個需要的時候被調用。Command模式是回調機制的一個面向對象的替代品。 在不同的時刻指定、排列和執行請求。一個Command對象可以有一個與初始請求無關的生存期。如果一個請求的接收者可用一種與地址空間無關的方式表達,那麼就可將負責該請求的命令對象傳送給另一個不同的進程並在那兒實現該請求。 支持取消操作。Command的Execute操作可在實施操作前將狀態存儲起來,在取消操作時這個狀態用來消除該操作的影響。Command介面必須添加一個Execute操作,該操作取消上一次Execute調用的效果。執行的命令被存儲在一個歷史列表中。可通過向後和向前遍歷這一列表並分別調用Unexecute和Execute來實現重數不限的「取消」和「重做」。 支持修改日誌,這樣當系統崩潰時,這些修改可以被重做一遍。在Command介面中添加裝載操作和存儲操作,可以用來保持變動的一個一致的修改日誌。從崩潰中恢復的過程包括從磁碟中重新讀入記錄下來的命令並用Execute操作重新執行它們。 用構建在原語操作上的高層操作構造一個系統。這樣一種結構在支持事務(Transaction)的信息系統中很常見。一個事務封裝了對數據的一組變動。Command模式提供了對事務進行建模的方法。Command有一個公共的介面,使得你可以用同一種方式調用所有的事務。同時使用該模式也易於添加新事務以擴展系統。 意圖
給定一個語言,定義它的文法的一種表示,並定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。
適用性 當有一個語言需要解釋執行, 並且你可將該語言中的句子表示為一個抽象語法樹時,可使用解釋器模式。而當存在以下情況時該模式效果最好: 該文法簡單對於復雜的文法, 文法的類層次變得龐大而無法管理。此時語法分析程序生成器這樣的工具是更好的選擇。它們無需構建抽象語法樹即可解釋表達式, 這樣可以節省空間而且還可能節省時間。 效率不是一個關鍵問題最高效的解釋器通常不是通過直接解釋語法分析樹實現的, 而是首先將它們轉換成另一種形式。例如,正則表達式通常被轉換成狀態機。但即使在這種情況下, 轉換器仍可用解釋器模式實現, 該模式仍是有用的。 意圖
提供一種方法順序訪問一個聚合對象中各個元素, 而又不需暴露該對象的內部表示。
適用性 訪問一個聚合對象的內容而無需暴露它的內部表示。 支持對聚合對象的多種遍歷。 為遍歷不同的聚合結構提供一個統一的介面(即, 支持多態迭代)。 意圖
用一個中介對象來封裝一系列的對象交互。中介者使各對象不需要顯式地相互引用,從而使其耦合鬆散,而且可以獨立地改變它們之間的交互。
適用性 一組對象以定義良好但是復雜的方式進行通信。產生的相互依賴關系結構混亂且難以理解。 一個對象引用其他很多對象並且直接與這些對象通信,導致難以復用該對象。 想定製一個分布在多個類中的行為,而又不想生成太多的子類。 意圖
在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態。這樣以後就可將該對象恢復到保存的狀態。
適用性 必須保存一個對象在某一個時刻的(部分)狀態, 這樣以後需要時它才能恢復到先前的狀態。 如果一個用介面來讓其它對象直接得到這些狀態,將會暴露對象的實現細節並破壞對象的封裝性。 意圖
定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時, 所有依賴於它的對象都得到通知並被自動更新。
適用性 當一個抽象模型有兩個方面, 其中一個方面依賴於另一方面。將這二者封裝在獨立的對象中以使它們可以各自獨立地改變和復用。 當對一個對象的改變需要同時改變其它對象, 而不知道具體有多少對象有待改變。 當一個對象必須通知其它對象,而它又不能假定其它對象是誰。換言之,你不希望這些對象是緊密耦合的。 意圖
允許一個對象在其內部狀態改變時改變它的行為。對象看起來似乎修改了它的類。
適用性 一個對象的行為取決於它的狀態, 並且它必須在運行時刻根據狀態改變它的行為。 一個操作中含有龐大的多分支的條件語句,且這些分支依賴於該對象的狀態。這個狀態通常用一個或多個枚舉常量表示。通常, 有多個操作包含這一相同的條件結構。State模式將每一個條件分支放入一個獨立的類中。這使得你可以根據對象自身的情況將對象的狀態作為一個對象,這一對象可以不依賴於其他對象而獨立變化。 意圖
定義一系列的演算法,把它們一個個封裝起來, 並且使它們可相互替換。本模式使得演算法可獨立於使用它的客戶而變化。
適用性 許多相關的類僅僅是行為有異。「策略」提供了一種用多個行為中的一個行為來配置一個類的方法。 需要使用一個演算法的不同變體。例如,你可能會定義一些反映不同的空間/時間權衡的演算法。當這些變體實現為一個演算法的類層次時,可以使用策略模式。 演算法使用客戶不應該知道的數據。可使用策略模式以避免暴露復雜的、與演算法相關的數據結構。 一個類定義了多種行為, 並且這些行為在這個類的操作中以多個條件語句的形式出現。將相關的條件分支移入它們各自的Strategy類中以代替這些條件語句。 意圖
定義一個操作中的演算法的骨架,而將一些步驟延遲到子類中。Te m p l a t e M e t h o d 使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。
適用性 一次性實現一個演算法的不變的部分,並將可變的行為留給子類來實現。 各子類中公共的行為應被提取出來並集中到一個公共父類中以避免代碼重復。這是Opdyke和Johnson所描述過的「重分解以一般化」的一個很好的例子。首先識別現有代碼中的不同之處,並且將不同之處分離為新的操作。最後,用一個調用這些新的操作的模板方法來替換這些不同的代碼。 控制子類擴展。模板方法只在特定點調用「hook」操作,這樣就只允許在這些點進行擴展。 意圖
表示一個作用於某對象結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用於這些元素的新操作。
適用性 一個對象結構包含很多類對象,它們有不同的介面,而你想對這些對象實施一些依賴於其具體類的操作。 需要對一個對象結構中的對象進行很多不同的並且不相關的操作,而你想避免讓這些操作「污染」這些對象的類。Visitor使得你可以將相關的操作集中起來定義在一個類中。當該對象結構被很多應用共享時,用Visitor模式讓每個應用僅包含需要用到的操作。 定義對象結構的類很少改變,但經常需要在此結構上定義新的操作。改變對象結構類需要重定義對所有訪問者的介面,這可能需要很大的代價。如果對象結構類經常改變,那麼可能還是在這些類中定義這些操作較好。

『陸』 java常用的的設計模式和開發模式都有哪些

設計模式主要分三個類型、創建型、結構型和行為型。設計模式分:3種類型及23種模式。

JAVA中的開發模式:MVC是一個很常用的程序開發設計模式,M-Model(模型):封裝應用程序的狀態;V-View(視圖):表示用戶界面;C-Controller(控制器):對用戶的輸入作出反應,創建並設置模型。

(6)設計模式中訪問者模式定義擴展閱讀

創建型模式:單例模式、抽象工廠模式、建造者模式、工廠模式、原型模式。

結構型模式:適配器模式、橋接模式、裝飾模式、組合模式、外觀模式、享元模式、代理模式。

行為型模式:模版方法模式、命令模式、迭代器模式、觀察者模式、中介者模式、備忘錄模式、解釋器模式(Interpreter模式)、狀態模式、策略模式、職責鏈模式(責任鏈模式)、訪問者模式。

『柒』 軟體設計模式主要有哪幾種

軟體設計模式主要有以下三大類共23種:

一、創建型模式:

1、工廠方法模式

工廠方法模式的創建是因為簡單工廠模式有一個問題,在簡單工廠模式中類的創建依賴工廠類,如果想要拓展程序,必須對工廠類進行修改,這違背了開閉原則,所以就出現了工廠方法模式,只需要創建一個工廠介面和多個工廠實現類。

子類可以自己決定實例化哪一個工廠類,client類針對抽象介面進行編程,如果需要增加新的功能,繼承工廠介面,直接增加新的工廠類就可以了,創建過程延遲到子類中進行,不需要修改之前的代碼,滿足了開閉原則,達到靈活地生產多種對象。

2、抽象工廠模式

抽象工廠模式是提供一個創建一系列相關或相互依賴對象的介面,而無需指定它們具體的類。區別於工廠方法模式的地方,工廠方法模式是創建一個工廠,可以實現多種對象;而抽象工廠模式是提供一個抽象工廠介面,裡面定義多種工廠,每個工廠可以生產多種對象。

前者的重點在於"怎麼生產",後者的重點在於"生產哪些";前者是一個抽象產品類,可以派生出多個具體產品類,後者是多個抽象產品類,每個抽象產品類可以派生出多個具體產品類。

3、單例模式

單例模式能保證一個類僅有一個實例,並提供一個訪問它的全局訪問點,同時在類內部創造單一對象,通過設置許可權,使類外部無法再創造對象。單例對象能保證在一個JVM中,該對象只有一個實例存在。

在創建的時候,省去了new操作符,降低了系統內存的使用頻率,減輕了系統的壓力。同時單例模式保證在一個jvm中僅存在一個實例的好處就在於好比一個軍隊當中只會存在一個最高級別的軍官來指揮整個軍隊,這樣才能保證獨立控制整個過程,否則如果出現多個,肯定會雜亂無序。

4、建造者模式

建造者模式是將一個復雜的構建與其表示相分離,使得同樣的構建過程可以創建不同的表示。在程序當中就是將一些不會變的基本組件,通過builder來進行組合,構建復雜對象,實現分離。

這樣做的好處就在於客戶端不必知道產品內部組成的細節;同時具體的建造者類之間是相互獨立的,對系統的擴展非常有利,滿足開閉原則;由於具體的建造者類是獨立的,因此可以對建造過程逐步細化,而不對其他的模塊產生任何影響。

5、原型模式

原型模式是用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。其實就是將對象復制了一份並返還給調用者,對象需繼承Cloneable並重寫clone()方法。原型模式的思想就是將一個對象作為原型,對其進行復制、克隆,產生一個和原對象類似的新對象。

分為淺復制和深復制,前者是將一個對象復制後,基本數據類型的變數都會重新創建,而引用類型,指向的還是原對象所指向的;後者是將一個對象復制後,不論是基本數據類型還有引用類型,都是重新創建的。

二、結構型模式:

1、適配器模式

適配器模式是使得原本由於介面不兼容而不能一起工作的那些類可以一起工作,銜接兩個不兼容、獨立的介面的功能,使得它們能夠一起工作,適配器起到中介的作用。

2、裝飾模式

裝飾器模式是動態地給一個對象添加一些額外的職責,給一個對象增加一些新的功能,要求裝飾對象和被裝飾對象實現同一個介面,裝飾對象持有被裝飾對象的實例。除了動態的增加,也可以動態的撤銷,要做到動態的形式,不可以用繼承實現,因為繼承是靜態的。

3、代理模式

代理模式是為其他對象提供一種代理以控制對這個對象的訪問,也就是創建類的代理類,間接訪問被代理類的過程中,對其功能加以控制。

它和裝飾器模式的區別在於,裝飾器模式為了增強功能,而代理模式是為了加以控制。代理模式就是多一個代理類出來,替原對象進行一些操作,例如買火車票不一定在火車站買,也可以去代售點。再比如打官司需要請律師,因為律師在法律方面有專長,可以替我們進行操作。

4、外觀模式

外觀模式是為子系統中的一組介面提供一個一致的界面,外觀模式定義了一個高層介面,這個介面使得這一子系統更加容易使用。

在客戶端和復雜系統之間再加一層,提供一個容易使用的外觀層。外觀模式是為了解決類與類之家的依賴關系的,外觀模式就是將他們的關系放在一個Facade類中,降低了類類之間的耦合度,比如搜狐門戶網站,就利用了外觀模式。

5、橋接模式

橋接模式是將抽象部分與實現部分分離,使它們都可以獨立的變化。橋接模式就是把事物和其具體實現分開,使他們可以各自獨立的變化(突然聯想到了mvc模式)。

將抽象化與實現化解耦,使得二者可以獨立變化,就好比現在常說的mvc模式,view和model之間通過control來控制,達到高內聚低耦合來解耦的目的。

6、組合模式

組合模式是將對象組合成樹形結構以表示"部分-整體"的層次結構,組合模式使得用戶對單個對象和組合對象的使用具有一致性。

創建了一個包含自己對象組的類,並提供修改對象組的方法。在系統的文件和文件夾的問題上就使用了組合模式,文件下不可以有對象,而文件夾下可以有文件對象或者文件夾對象。

7、享元模式

享元模式是運用共享技術有效地支持大量細粒度的對象。享元模式的主要目的是實現對象的共享,即共享池,當系統中對象多的時候可以減少內存的開銷,重用現有的同類對象,若未找到匹配的對象,則創建新對象,這樣可以減少對象的創建,降低系統內存,提高效率。

三、行為型模式:

1、策略模式

策略模式是定義一系列的演算法,把它們一個個封裝起來,並且使它們可相互替換,且演算法的變化不會影響到使用演算法的客戶。

為了統一介面下的一系列演算法類(也就是多種策略),用一個類將其封裝起來,使這些策略可動態切換。策略模式屬於行為型模式,是為了使這些策略可以相互切換,是為了選擇不同的行為。

2、模版方法模式

模板方法模式是定義一個操作中的演算法的骨架,而將一些步驟延遲到子類中。該模式就是在一個抽象類中,有一個主方法,再定義1...n個方法,可以是抽象的,也可以是實際的方法,定義一個類,繼承該抽象類,重寫抽象方法,通過調用抽象類,實現對子類的調用。

模板方法使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟,將一些固定步驟、固定邏輯的方法封裝成模板方法。調用模板方法即可完成那些特定的步驟。

3、觀察者模式

觀察者模式是定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並被自動更新。

也就是當被觀察者狀態變化時,通知所有觀察者,這種依賴方式具有雙向性,在QQ郵箱中的郵件訂閱和RSS訂閱,當用戶瀏覽一些博客時,經常會看到RSS圖標,簡單來說就是當訂閱了該文章,如果後續有更新,會及時通知用戶。這種現象即是典型的觀察者模式。

4、迭代器模式

迭代器模式是提供一種方法順序訪問一個聚合對象中各個元素,而又無須暴露該對象的內部表示。

在Java當中,將聚合類中遍歷各個元素的行為分離出來,封裝成迭代器,讓迭代器來處理遍歷的任務;使簡化聚合類,同時又不暴露聚合類的內部,在我們經常使用的JDK中各個類也都是這些基本的東西。

5、責任鏈模式

責任鏈模式是避免請求發送者與接收者耦合在一起,讓多個對象都有可能接收請求,將這些對象連接成一條鏈,並且沿著這條鏈傳遞請求,直到有對象處理它為止。有多個對象,每個對象持有對下一個對象的引用,這樣就會形成一條鏈,請求在這條鏈上傳遞,直到某一對象決定處理該請求。

但是發出者並不清楚到底最終那個對象會處理該請求。在生活中學生進行請假的過程中,會涉及到,學生請假會一級一級往上批,最終處理,具體由誰批准可能不清楚。在程序當中,現在使用的struts攔截器即用到了責任鏈模式。

6、命令模式

命令模式是將一個請求封裝成一個對象,從而使發出者可以用不同的請求對客戶進行參數化。模式當中存在調用者、接收者、命令三個對象,實現請求和執行分開;調用者選擇命令發布,命令指定接收者。

7、備忘錄模式

備忘錄模式是在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態。創建一個備忘錄類,用來存儲原始類的信息;同時創建備忘錄倉庫類,用來存儲備忘錄類,主要目的是保存一個對象的某個狀態,以便在適當的時候恢復對象,也就是做個備份。

在系統當中使用的撤銷操作,即是使用了備忘錄模式,系統可以保存有限次數的文件狀態,用戶可以進行上幾個狀態的恢復,也就是用到了備忘錄模式。

8、狀態模式

狀態模式是允許對象在內部狀態發生改變時改變它的行為。對象具有多種狀態,且每種狀態具有特定的行為。

在網站的積分系統中,用戶具有不同的積分,也就對應了不同的狀態;還有QQ的用戶狀態有幾種狀態,在線、隱身、忙碌等,每個狀態對應不同的操作,而且你的好友也能看到你的狀態。

9、訪問者模式

訪問者模式主要是將數據結構與數據操作分離。在被訪問的類裡面加一個對外提供接待訪問者的介面,訪問者封裝了對被訪問者結構的一些雜亂操作,解耦結構與演算法,同時具有優秀的擴展性。通俗來講就是一種分離對象數據結構與行為的方法。

通過這種分離,可達到為一個被訪問者動態添加新的操作而無需做其它的修改的效果。訪問者模式的優點是增加操作很容易,因為增加操作意味著增加新的訪問者。訪問者模式將有關行為集中到一個訪問者對象中,其改變不影響系統數據結構。

10、中介者模式

中介者模式是用一個中介對象來封裝一系列的對象交互,中介者使各對象不需要顯式地相互引用,從而使其耦合鬆散,而且可以獨立地改變它們之間的交互。

例如,MVC模式中control就是model和view的中介者。與適配器區別在於,適配器是為了兼容不同的介面,而中介者是為了將顯示和操作分離。

11、解釋器模式

解釋器模式是給定一個語言,定義它的文法表示,並定義一個解釋器,這個解釋器使用該標識來解釋語言中的句子,基本也就用在這個范圍內,適用面較窄,例如:正則表達式的解釋等。

參考資料來源:網路-軟體設計模式

『捌』 設計模式都有哪些

總體來說設計模式分為三大類:

一、創建型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。

二、結構型模式,共七種:適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。

三、行為型模式,共十一種:策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、解釋器模式。

1、工廠方法模式:

定義一個用於創建對象的介面,讓子類決定實例化哪一個類。Factory Method 使一個類的實例化延遲到其子類。

工廠模式有一個問題就是,類的創建依賴工廠類,也就是說,如果想要拓展程序,必須對工廠類進行修改,這違背了閉包原則,所以,從設計角度考慮,有一定的問題,這就用到工廠方法模式。

創建一個工廠介面和創建多個工廠實現類,這樣一旦需要增加新的功能,直接增加新的工廠類就可以了,不需要修改之前的代碼。

2、抽象工廠模式:

提供一個創建一系列相關或相互依賴對象的介面,而無需指定它們具體的類。抽象工廠需要創建一些列產品,著重點在於"創建哪些"產品上,也就是說,如果你開發,你的主要任務是劃分不同差異的產品線,並且盡量保持每條產品線介面一致,從而可以從同一個抽象工廠繼承。

3、單例模式:

單例對象(Singleton)是一種常用的設計模式。在Java應用中,單例對象能保證在一個JVM中,該對象只有一個實例存在。這樣的模式有幾個好處:

(1)某些類創建比較頻繁,對於一些大型的對象,這是一筆很大的系統開銷。

(2)省去了new操作符,降低了系統內存的使用頻率,減輕GC壓力。

(3)有些類如交易所的核心交易引擎,控制著交易流程,如果該類可以創建多個的話,系統完全亂了。(比如一個軍隊出現了多個司令員同時指揮,肯定會亂成一團),所以只有使用單例模式,才能保證核心交易伺服器獨立控制整個流程。

4、建造者模式:

將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。

5、原型模式:

原型模式雖然是創建型的模式,但是與工程模式沒有關系,從名字即可看出,該模式的思想就是將一個對象作為原型,對其進行復制、克隆,產生一個和原對象類似的新對象。本小結會通過對象的復制,進行講解。在Java中,復制對象是通過clone()實現的,先創建一個原型類。

6、適配器模式:

適配器模式將某個類的介面轉換成客戶端期望的另一個介面表示,目的是消除由於介面不匹配所造成的類的兼容性問題。主要分為三類:類的適配器模式、對象的適配器模式、介面的適配器模式。

7、裝飾器模式:

顧名思義,裝飾模式就是給一個對象增加一些新的功能,而且是動態的,要求裝飾對象和被裝飾對象實現同一個介面,裝飾對象持有被裝飾對象的實例。

8、代理模式:

代理模式就是多一個代理類出來,替原對象進行一些操作,比如我們在租房子的時候回去找中介,為什麼呢?因為你對該地區房屋的信息掌握的不夠全面,希望找一個更熟悉的人去幫你做,此處的代理就是這個意思。

9、外觀模式:

外觀模式是為了解決類與類之家的依賴關系的,像spring一樣,可以將類和類之間的關系配置到配置文件中,而外觀模式就是將他們的關系放在一個Facade類中,降低了類類之間的耦合度,該模式中沒有涉及到介面。

10、橋接模式:

橋接模式就是把事物和其具體實現分開,使他們可以各自獨立的變化。橋接的用意是:將抽象化與實現化解耦,使得二者可以獨立變化,像我們常用的JDBC橋DriverManager一樣。

JDBC進行連接資料庫的時候,在各個資料庫之間進行切換,基本不需要動太多的代碼,甚至絲毫不用動,原因就是JDBC提供統一介面,每個資料庫提供各自的實現,用一個叫做資料庫驅動的程序來橋接就行了。

11、組合模式:

組合模式有時又叫部分-整體模式在處理類似樹形結構的問題時比較方便。使用場景:將多個對象組合在一起進行操作,常用於表示樹形結構中,例如二叉樹,數等。

12、享元模式:

享元模式的主要目的是實現對象的共享,即共享池,當系統中對象多的時候可以減少內存的開銷,通常與工廠模式一起使用。

13、策略模式:

策略模式定義了一系列演算法,並將每個演算法封裝起來,使其可以相互替換,且演算法的變化不會影響到使用演算法的客戶。需要設計一個介面,為一系列實現類提供統一的方法,多個實現類實現該介面,設計一個抽象類(可有可無,屬於輔助類),提供輔助函數。

14、模板方法模式:

一個抽象類中,有一個主方法,再定義1...n個方法,可以是抽象的,也可以是實際的方法,定義一個類,繼承該抽象類,重寫抽象方法,通過調用抽象類,實現對子類的調用。

15、觀察者模式:

觀察者模式很好理解,類似於郵件訂閱和RSS訂閱,當我們瀏覽一些博客或wiki時,經常會看到RSS圖標,就這的意思是,當你訂閱了該文章,如果後續有更新,會及時通知你。

其實,簡單來講就一句話:當一個對象變化時,其它依賴該對象的對象都會收到通知,並且隨著變化!對象之間是一種一對多的關系。

16、迭代子模式:

顧名思義,迭代器模式就是順序訪問聚集中的對象,一般來說,集合中非常常見,如果對集合類比較熟悉的話,理解本模式會十分輕松。這句話包含兩層意思:一是需要遍歷的對象,即聚集對象,二是迭代器對象,用於對聚集對象進行遍歷訪問。

17、責任鏈模式:

責任鏈模式,有多個對象,每個對象持有對下一個對象的引用,這樣就會形成一條鏈,請求在這條鏈上傳遞,直到某一對象決定處理該請求。但是發出者並不清楚到底最終那個對象會處理該請求,所以,責任鏈模式可以實現,在隱瞞客戶端的情況下,對系統進行動態的調整。

18、命令模式:

命令模式的目的就是達到命令的發出者和執行者之間解耦,實現請求和執行分開。

19、備忘錄模式:

主要目的是保存一個對象的某個狀態,以便在適當的時候恢復對象,個人覺得叫備份模式更形象些,通俗的講下:假設有原始類A,A中有各種屬性,A可以決定需要備份的屬性,備忘錄類B是用來存儲A的一些內部狀態,類C呢,就是一個用來存儲備忘錄的,且只能存儲,不能修改等操作。

20、狀態模式:

狀態模式在日常開發中用的挺多的,尤其是做網站的時候,我們有時希望根據對象的某一屬性,區別開他們的一些功能,比如說簡單的許可權控制等。

21、訪問者模式:

訪問者模式把數據結構和作用於結構上的操作解耦合,使得操作集合可相對自由地演化。訪問者模式適用於數據結構相對穩定演算法又易變化的系統。因為訪問者模式使得演算法操作增加變得容易。

若系統數據結構對象易於變化,經常有新的數據對象增加進來,則不適合使用訪問者模式。訪問者模式的優點是增加操作很容易,因為增加操作意味著增加新的訪問者。訪問者模式將有關行為集中到一個訪問者對象中,其改變不影響系統數據結構。其缺點就是增加新的數據結構很困難。

22、中介者模式:

中介者模式也是用來降低類類之間的耦合的,因為如果類類之間有依賴關系的話,不利於功能的拓展和維護,因為只要修改一個對象,其它關聯的對象都得進行修改。

如果使用中介者模式,只需關心和Mediator類的關系,具體類類之間的關系及調度交給Mediator就行,這有點像spring容器的作用。

23、解釋器模式:

解釋器模式一般主要應用在OOP開發中的編譯器的開發中,所以適用面比較窄。

(8)設計模式中訪問者模式定義擴展閱讀:

介紹三本關於設計模式的書:

1、《設計模式:可復用面向對象軟體的基礎》

作者:[美] Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides

出版社: 機械工業出版社

2、《軟體秘笈:設計模式那點事》

作者:鄭阿奇

出版社:電子工業出版社

3、《設計模式:基於C#的工程化實現及擴展》

作者:王翔

出版社:電子工業出版社

『玖』 24種設計模式

一、創建型模式 

1、抽象工廠模式(Abstract factory pattern): 提供一個介面, 用於創建相關或依賴對象的家族, 而不需要指定具體類. 

2、生成器模式(Builder pattern): 使用生成器模式封裝一個產品的構造過程, 並允許按步驟構造. 將一個復雜對象的構建與它的表示分離, 使得同樣的構建過程可以創建不同的表示. 

3、工廠模式(factory method pattern): 定義了一個創建對象的介面, 但由子類決定要實例化的類是哪一個. 工廠方法讓類把實例化推遲到子類. 

4、原型模式(prototype pattern): 當創建給定類的實例過程很昂貴或很復雜時, 就使用原形模式. 

5、單例了模式(Singleton pattern): 確保一個類只有一個實例, 並提供全局訪問點. 

6、多例模式(Multition pattern): 在一個解決方案中結合兩個或多個模式, 以解決一般或重復發生的問題. 

二、結構型模式 

1、適配器模式(Adapter pattern): 將一個類的介面, 轉換成客戶期望的另一個介面. 適配器讓原本介面不兼容的類可以合作無間. 對象適配器使用組合, 類適配器使用多重繼承. 

2、橋接模式(Bridge pattern): 使用橋接模式通過將實現和抽象放在兩個不同的類層次中而使它們可以獨立改變. 

3、組合模式(composite pattern): 允許你將對象組合成樹形結構來表現」整體/部分」層次結構. 組合能讓客戶以一致的方式處理個別對象以及對象組合. 

4、裝飾者模式(decorator pattern): 動態地將責任附加到對象上, 若要擴展功能, 裝飾者提供了比繼承更有彈性的替代方案. 

5、外觀模式(facade pattern): 提供了一個統一的介面, 用來訪問子系統中的一群介面. 外觀定義了一個高層介面, 讓子系統更容易使用. 

6、亨元模式(Flyweight Pattern): 如想讓某個類的一個實例能用來提供許多」虛擬實例」, 就使用蠅量模式. 

7、代理模式(Proxy pattern): 為另一個對象提供一個替身或佔位符以控制對這個對象的訪問. 

三、行為型模式 

1、責任鏈模式(Chain of responsibility pattern): 通過責任鏈模式, 你可以為某個請求創建一個對象鏈. 每個對象依序檢查此請求並對其進行處理或者將它傳給鏈中的下一個對象. 

2、命令模式(Command pattern): 將」請求」封閉成對象, 以便使用不同的請求,隊列或者日誌來參數化其他對象. 命令模式也支持可撤銷的操作. 

3、解釋器模式(Interpreter pattern): 使用解釋器模式為語言創建解釋器. 

4、迭代器模式(iterator pattern): 提供一種方法順序訪問一個聚合對象中的各個元素, 而又不暴露其內部的表示. 

5、中介者模式(Mediator pattern) : 使用中介者模式來集中相關對象之間復雜的溝通和控制方式. 

6、備忘錄模式(Memento pattern): 當你需要讓對象返回之前的狀態時(例如, 你的用戶請求」撤銷」), 你使用備忘錄模式. 

7、觀察者模式(observer pattern): 在對象之間定義一對多的依賴, 這樣一來, 當一個對象改變狀態, 依賴它的對象都會收到通知, 並自動更新. 

8、狀態模式(State pattern): 允許對象在內部狀態改變時改變它的行為, 對象看起來好象改了它的類. 

9、策略模式(strategy pattern): 定義了演算法族, 分別封閉起來, 讓它們之間可以互相替換, 此模式讓演算法的變化獨立於使用演算法的客戶. 

10、模板方法模式(Template pattern): 在一個方法中定義一個演算法的骨架, 而將一些步驟延遲到子類中. 模板方法使得子類可以在不改變演算法結構的情況下, 重新定義演算法中的某些步驟. 

11、訪問者模式(visitor pattern): 當你想要為一個對象的組合增加新的能力, 且封裝並不重要時, 就使用訪問者模式.

『拾』 Java中23種設計模式,哪些是必須了解的

一共23種設計模式!

引用《軟體秘笈-設計模式那點事》書籍:

按照目的來分,設計模式可以分為創建型模式、結構型模式和行為型模式。
創建型模式用來處理對象的創建過程;結構型模式用來處理類或者對象的組合;行為型模式用來對類或對象怎樣交互和怎樣分配職責進行描述。

創建型模式用來處理對象的創建過程,主要包含以下5種設計模式:
 工廠方法模式(Factory Method Pattern)
 抽象工廠模式(Abstract Factory Pattern)
 建造者模式(Builder Pattern)
 原型模式(Prototype Pattern)
 單例模式(Singleton Pattern)

結構型模式用來處理類或者對象的組合,主要包含以下7種設計模式:
 適配器模式(Adapter Pattern)
 橋接模式(Bridge Pattern)
 組合模式(Composite Pattern)
 裝飾者模式(Decorator Pattern)
 外觀模式(Facade Pattern)
 享元模式(Flyweight Pattern)
 代理模式(Proxy Pattern)

行為型模式用來對類或對象怎樣交互和怎樣分配職責進行描述,主要包含以下11種設計模式:
 責任鏈模式(Chain of Responsibility Pattern)
 命令模式(Command Pattern)
 解釋器模式(Interpreter Pattern)
 迭代器模式(Iterator Pattern)
 中介者模式(Mediator Pattern)
 備忘錄模式(Memento Pattern)
 觀察者模式(Observer Pattern)
 狀態模式(State Pattern)
 策略模式(Strategy Pattern)
 模板方法模式(Template Method Pattern)
 訪問者模式(Visitor Pattern)