《研磨設計模式》--摘錄筆記(一)

《研磨設計模式》--摘錄筆記(一)

說明:本文檔大部分內容是從原書中摘錄出來的,使用步驟是自己總結提煉的。

目的:內容僅供自己溫習回顧使用。

提示:可能會存在摘錄不全或者總結不精確的問題。若是他人閱讀,僅供參考!---------dusuanyun 2016-0911

 

第一章:設計模式基礎

設計模式:是指在軟件開發中,經過驗證的,用於解決在特定環境下,重複出現的、特定問題的解決方案。

23種設計模式,GoF把它們分爲三類。

創建型模式:抽象了對象實例化過程,用來幫助創建對象的實例。

行爲型模式:描述算法和對象間職責的分配。

結構型模式:描述如何組合類和對象以獲得更大的結構。

 

要從思想上和方法上吸收設計模式的精鍵,並融入到自己的思路中,在進行軟件的分析和設計的時候,能隨意地、自然而然地應用,就如同自己思維的一部分.

 

2 章 簡單工廠(GoF的著作中沒有)

定義:提供一個創建對象實例的功能,而無須關心其具體實現。被創建實例的類型可以是接口、 抽象,也可以是具體的類。

本質:選擇實現

使用步驟:

1.創建一個xxxFactory的工廠類;2.定義客戶所需要的功能接口-API3.定義API的具體實現類(可以有多個)

4.xxxFactory類中提供靜態(static)方法:createAPI(),在方法中new具體的實現類賦予API,返回類型爲API

createAPI(),可以有參數,在方法內部選擇不同的實現類。

優點:幫助封裝;解耦

缺點:可能增加客戶端的複雜度;不方便擴張子工廠。

易混模式:

A.抽象工廠模式:如果抽象工廠退化成只有一個實現,不分層次,那麼就相當於簡單工廠了。

B.工廠方法模式:如果把工廠方法中選擇的實現放到父類中直接實現,那就等同於簡單工廠。

何時選用:

如果想要完全封裝隔離具體實現,讓外部只能通過接口來操作封裝體,那麼可以選用簡單工廠,讓客戶端通過工廠來獲取相應的接口,而無須關心具體的實現。

如果想要把對外創建對象的職責集中管理和控制,可以選用簡單工廠,一個簡單工廠可以創建很多的、不相關的對象,可以把對外創建對象的職責集中到一個簡單工廠來,從而實現集中管理和控制。

 

3 外觀模式(GoF的著作中劃分爲結構型)

定義:爲子系統中的一組接口提供一個一致的界面, Facade模式定義了一個高層接口, 這個接口使得這一子系統更加容易使用。

本質:封裝交互,簡化調用

使用步驟:

1.定義多個模塊的功能接口--APIeg:xxxModuleAPI; 2.定義API的具體實現類,eg:xxxModuleImpl;

3.定義一個xxxFacade的外觀類,外觀類定義供客戶端調用的方法,在方法中需要什麼具體的實現類就new什麼。

優點:鬆散耦合;簡單易用;更好地劃分訪問層次。

缺點:過多或不太合理的Facade也容易讓人迷惑,到底是調用Facade好呢,還是直接調用模塊好。

易混模式:中介者模式

外觀模式是封裝內部,方便外部使用;中介者模式是都是同事之間的關係,不分內外------自己總結的

何時選用:

1.如果你希望爲一個複雜的子系統提供一個單接口的時候,可以考慮使用外觀模式。

2.如果想要讓客戶程序,和抽象類的實現部分鬆散耦合,可以考慮使用外觀模式,

3.如果構建多層結構的系統,可以考慮、使用外觀棋式,使用外觀對象作爲每層的入口, 這樣可以簡化層問調用,也可以鬆散層次之間的依賴關係。

 

4  適配器模式(GoF的著作中劃分爲結構型)

定義:將一個類的接口轉換成客戶希望的另外一個接口。適配器模式使得原本由於接口不兼容而不能一起工作的那些類可以一起工作。

本質:轉換匹配,複用功能。

使用步驟:【涉及名詞】Target:定義客戶端需要的跟特定領域相關的接口。

Adaptee:己經存在的接口,通常能滿足客戶端的功能要求,但是接口與客戶端要求的特定領域接口不一致,需要被適配。

Adapter:適配器,把Adaptee適配成爲Client需要的Target

1.定義xxxTarget接口;2.定義xxxAdapter實現xxxTarget

3.xxxAdapter中,定義保存xxxAdaptee的私有屬性;

4.xxxAdapter的構造方法中以參數的形式,傳入xxxAdaptee,在構造方法中對xxxAdaptee的私有屬性賦值。

5.在xxxAdapter的構造方法中,提供需要的轉換方法。

6.客戶端使用,先創建要適配的xxxAdaptee,創建xxxTarget並進行使用xxxAdaptee爲參數進行初始化,最後調用xxxTarget提供轉換的方法。

 

優點:更好的複用性;更好的可擴展性。

缺點:過多地使用適配器,會讓系統非常凌亂,不容易整體進行把握。

易混模式:---

何時選用:

• 如果你想要使用一個已經存在的類,但是它的接口不符合你的需求,這種情況可以使用適配器模式,來把已有的實現轉換成你需要的接口。

• 如果你想創建一個可以複用的類,這個類可能和一些不兼容的類一起工作,這種情況可以使用適配器模式,到時候需要什麼就適配什麼。

• 如果你想使用一些已經存在的子類,但是不可能對每一個子類都進行適配,這種情況可以選用對象適配器,直接適配這些子類的父類就可以了。

 

5  單例模式(GoF的著作中劃分爲創建型)

定義:保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。

本質:控制實例數目。

使用步驟:分爲飽漢式和餓漢式

懶漢式步驟

1.私有化構造方法;2.提供獲取實例的靜態(static)方法getInstance();3.定義存儲實例的靜態(static)私有(private)屬性;4.控制實例的創建,如果存儲實例的屬性不爲null,則返回屬性值,否則創建實例並對屬性賦值。

餓漢式步驟:和上面的區別

1.在定義存儲實例的靜態(static)私有(private)屬性時,直接初始化---new了;

2.getInstance()不在判斷屬性爲null了,直接返回屬性值。

優點:時間空間;線程安全

缺點:

易混模式:---

何時選用:

當需要控制一個類的實例只能有一個,而且客戶只能從一個全局訪問點訪問它時,可以選用單例模式,這些功能恰好是單例模式要解決的問題。

 


6  工廠方法模式(GoF的著作中劃分爲創建型)

定義:定義一個用於創建對象的接口,讓子類決定實例化哪一個類,FactorMethod使一個類的實例化延遲到子類。

本質:延遲到子類來選擇實現。

使用步驟:【涉及名詞】

Product:定義工廠方法所創建的對象的接口, 也就是實際需要使用的對象的接口。

ConcreteProduct 具體的Product 接口的實現對象。

Creator 創建器,聲明工廠方法,工廠方法通常會返回一個Product 類型的實例對象,而且多是抽象方法。也可以在Creator 裏面提供工廠方法的默認實現,讓工廠方法返回一個缺省的Product 類型的實例對象。

ConcreteCreator :具體的創建器對象, 覆蓋實現Creator 定義的工廠方法, 返回具體的Product 實例。

 

1.定義Product接口對象;2.定義實現Product接口對象ConcreteProduct3.定義創建器的抽象(abstract)Creator

4.定義具體的創建器對象ConcreteCreator,並繼承Creator

5.ConcreteCreator中定義protected Product factoryMethod(),在方法中new ConcreteProduct()並返回。

 

優點:可以在不知具體實現的情況下開始編程;更容易擴展對象的新版本;連接平行的類層次。

缺點:具體產品對象和工廠方法的耦合性。

何時選用:

1.如果一個類需要創建某個接口對象,但是又不知道具體的實現,這種情況可以選用工廠方法模式,把創建對象的工作延遲到子類中去實現。

2.如果一個類本身就希望由它的子類來創建所需的對象的時候,應該使用工廠方法模式。

 

 

7 章 抽象工廠模式(GoF的著作中劃分爲創建型)

定義:提供一個創建系列相關或相互依賴對象的接口,而無需指定它們具體的類。

本質:選擇產品簇的實現。

使用步驟:【涉及名詞】

Abstract Factory:抽象工廠,定義創建一系列產品對象的操作接口。

Concrete Factory:具體的工廠,實現抽象工廠定義的方法,具體實現一系列產品對象的創建。

Abstract Product:定義一類產品對象的接口。

Concrete Product:具體的產品實現對象,通常在具體工廠裏面,會選擇具體的產品實現對象,來創建符合抽象工廠定義的方法返回的產品類型的對象。

Client:客戶端,主要使用抽象工廠來獲取一系列所需要的產品對象,然後面向這些產品對象的接口編程,以實現需要的功能。

1.定義抽象工廠AbstractFactory接口;2.定義抽象產品Abstract Product的接口,egAbstractProductAAbstract ProductB接口;

3.定義具體產品實現對象ConcreteProduct,實現Abstract Product的接口,egConcreteProductAConcreteProductB

4.具體工廠ConcreteFactory實現抽象工廠AbstractFactoryegConcreteFactory1ConcreteFactory2...

5.在具體的ConcreteFactory1中實現創建具體相關的產品對象。EgcreateProductA()createProductB()

 在具體的ConcreteFactory2中實現創建具體相關的產品對象。EgcreateProductA2()createProductB2()

6.客戶端在使用抽象工廠功能時,創建(new)指定的ConcreteFactoryegConcreteFactory1

其實ConcreteFactoryN就好像schemaN,對應方案一、方案二...

 

優點:分離接口和實現;使得切換產品簇變得容易。

缺點:不太容易擴展新的產品;容易造成類層次複雜。

何時選用:

1. 如果希望一個系統獨立於它的產品的創建、組合和表示的時候。換句話說希望一個系統,只是知道產品的接口,而不關心實現的時候。

2.如果一個系統要由多個產品系列中的一個來配置的時候。換句話說可以動態切換產品簇的時候。

3.如果要強調一系列相關產品的接口,以便聯合使用它們的時候。

 

8  生成器模式(GoF的著作中分爲創建型)

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

本質:分離整體構建算法和部件構造。

使用步驟:【涉及名詞】

Builder:生成器接口,定義創建一個Product對象所需的各個部件的操作。

ConcreteBuilder: 具體的生成器實現,實現各個部件的創建, 並負責組裝Product對象的各個部件, 同時還提供一個讓用戶獲取組裝完成後的產品對象的方法。

Director:指導者,也被稱爲導向者, 主要用來使用Builder接口,以一個統一的過程來構建所需要的Product對象。

Product:產品,表示被生成器構建的複雜對象, 包含多個部件。

1.定義生成器接口Builder2.定義具體生成器實現類ConcreteBuilder實現Builder

3.定義被構建的產品對象接口Product4.定義指導者類Director,在Director定義私有屬性builder來存儲,使用構造函數傳進來的Builder。構造函數含有參數Builder

5.在指導者Director中提供構造方法,在該方法中調用具體的builder的構造功能!

 

優點:鬆散耦合;可以很容易的改變產品內部的表示;更好的複用性。

缺點:---

何時選用:

1.如果創建對象的算法,應該獨立於該對象的組成部分以及它們的裝配方式時。

2.如果同一個構建過程有着不同的表示時。

 

 

9 章 原型模式(GoF的著作中劃分爲創建型)

定義:用原型實例指定創建對象的種類,並通過拷貝這些原型創建新的對象。

本質:克隆生成對象。

使用步驟:【涉及名詞】

Prototype: 聲明一個克隆自身的接口,用來約束想要克隆自己的類,要求它們都要實現這裏定義的克隆方法;

ConcretePrototype: 實現Prototype接口的類, 這些類真正實現克隆自身的功能;

Client:使用原型的客戶端, 首先要獲取到原型實例對象,然後通過原型實例克隆自身來創建新的對象實例。

1.定義原型接口---Prototype2.定義實現原型接口實現類ConcretePrototype來實現PrototypeegConcretePrototypeAConcretePrototypeB....

3.客戶端Client直接調用對象實例的clone()方法創建新的實例。

 

優點:對客戶端隱藏具體的實現類型;在運行時動態改變具體的實現類型。

缺點:最大的缺點就在於每個原型的子類都必須實現clone的操作,尤其包含引用類型的對象時 clone方法會比較麻煩, 必須要能夠遞歸地讓所有的相關對象都要正確地實現克降。

何時選用:

• 如果一個系統想要獨立於它想要使用的對象時,可以使用原型模式,讓系統只面向接口編程,在系統需要新的對象的時候,可以通過克隆原型來得到。

• 如果需要實例化的類是在運行時刻動態指定時,可以使用原型模式,通過克隆原型來得到需要的實例。


 

10 章 中介者模式(GoF的著作中劃分爲行爲型)

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

本質:封裝交互。

使用步驟:【涉及名詞】

• Mediator:中介者接口。在裏面定義各個同事之間交互需要的方法,可以是公共的通信方法,比如changed 方法,大家都用,也可以是小範圍的交互方法。

• ConcreteMediator:具體中介者實現對象。它需要了解並維護各個同事對象,並負責具體的協調各同事對象的交互關係。

• Colleague:同事類的定義,通常實現成爲抽象類,主要負責約束同事對象的類型,並實現一些具體同事類之間的公共功能.比如,每個具體同事類都應該知道中介者對象,也就是具體同事類都會持有中介者對象,都可以定義到這個類裏面。

• ConcreteColleague:具體的同事類,實現自己的業務,在需要與其他同事通信的時候,就與持有的中介者通信,中介者會負責與其他的同事交互。

 

1.定義所有同事的(抽象)父類Colleague2.Colleague中持有Mediator,同時構造函數以Mediator爲參數;

3.定義具體的ConcreteColleague實現ColleagueegConcreteColleagueAConcreteColleagueB ....

在具體的ConcreteColleague中的構造函數調用父類的實現(也是以Mediator爲參數),同時提供與其他同事交互的方法;

4.定義中介者接口Mediator,在此接口中提供以Colleague爲參數的changed()方法;

5.定義中介者接口的實現ConcreteMediator,在該對象中持有所有需要交互的同事對象,egConcreteColleagueAConcreteColleagueB ....

同時實現接口中changed()方法。

 

優點:鬆散耦合;集中控制交互;多對多變成一對多。

缺點: 過度集中化。如果同事對象的交互非常多,而且比較複雜,當這些複雜性全部集中到中介者的時候,會導致中介者對象變得十分的複雜,而且難以管理和維護。

何時選用:

1.如果一組對象之間的通信-方式比較複雜,導致相互依賴、結構混亂,可以採用中介者模式,把這些對象相互的交互管理起米, 每個對象都只需要和中介者交互,從而使得各個對象鬆散耦合,結構也更清晰易懂。

2.如果一個對象引用很多的對象,並直接跟這些對象交互,導致難以複用該對象,可以採用中介者模式,把這個對象跟其他對象的交互封裝到中介者對象裏面,這個對象只需要和中介者對象交互就可以了。

 

 

11章 代模式(GoF的著作中劃分爲結構型)

定義:爲其他對象提供一種代理以控制對這個對象的訪問。

本質:控制()對象訪問

使用步驟:【涉及名詞】

Proxy: 代理對象, 通常具有如下功能。實現與具體的目標對象一樣的接口, 這樣就可以使用代理來代替具體的目標對象。保存一個指向具體目標對象的引用, 可以在需要的時候調用具體的目標對象。

可以控制對具體目標對象的訪問, 並可以負責創建和刪除它。

Subject:目標接口, 定義代理和具體目標對象的接口, 這樣就可以在任何使用具體目標對象的地方使用代理對象。

RealSubject,具體的目標對象, 真正實現目標接口要求的功能。

1.定義目標接口Subject,並提供相關的接口方法;2.定義真實對象RealSubject實現Subject3.定義代理對象Proxy來實現Subject4.Proxy中持有RealSubject,且構造函數以RealSubject爲參數。

 

優點:---

缺點:---

何時選用:

1.要爲一個對象在不同的地址空間提供局部代表的時候,可以使用遠程代理.

2.需要按照需要創建開銷很大的對象的時候,可以使用虛代理。

3.需要控制對原始對象的訪問的時候,可以使用保護代理。

4.需要在訪問對象執行一些附加操作的時候,可以使用智能指引代理。

 

 

12  觀察者模式(GoF的著作中劃分爲行爲型)

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

本質:觸發聯動。

使用步驟:【涉及名詞】

Subject: 目標對象,通常具有如下功能。

• 一個目標可以被多個觀察者觀察。

• 目標提供對觀察者註冊和退訂的維護。

• 當目標的狀態發生變化時, 目標負責通知所有註冊的、有效的觀察者。

ConcreteSubject: 具體的目標實現對象,用來維護目標狀態, 當目標對象的狀態發生改變時, 通知所有註冊的、有效的觀察者,讓觀察者執行相應的處理。

Observer:定義觀察者的口,提供目標通知時對應的更新方法,這個更新方法進行相應的業務處理,可以在這個方法裏面回調目標對象,以獲取目標對象的數據。

ConeretObserver: 觀察者的具體實現對象,用來接收目標的通知, 並進行相應的後續處理,比如更新自身的狀態以保持和目標的相應狀態一致。

1.定義目標對象類Subject,在類中定義持有ObserverList,同時提供註冊、刪除、通知觀察者對象的方法;

2.具體目標對象ConcreteSubject繼承Subject,定義存儲當前狀態的屬性subjectStat,在setSubjectStat方法中,設置屬性後,調用父類的通知觀察者的方法;

3.定義觀察者接口Observer,其中提供以Subject爲參數的update()方法;

4.Observer的實現類ConeretObserver,持有存儲觀察者狀態的屬性observerStat,同時實現update方法,在update方法中,可以進行狀態對比,然後決定執行什麼操作。

 

Subject對象中的通知觀察者方法,核心是,遍歷List中的Observer,並調用Observerupdate方法。

優點:觀察者模式實現了觀察者和目標之間的抽象耦合;觀察者模式實現了動態聯動;觀察者模式支持廣播通信。

缺點:由於觀察者模式每次都是廣播通信,不管觀察者需不需要,每個觀察者都會被調用update方法,如果觀察者不需要執行相應處理,那麼這次操作就浪費了。其實浪費了還好,最怕引起誤更新,那就麻煩了...

何時選用:

• 當一個抽象模型有兩個方面, 其中一個方面的操作依賴於另一個方面的狀態變化,那麼就可以選用觀察者模式, 將這兩者封裝成觀察者和目標對象, 當目標對象變化的時候, 依賴於它的觀察者對象也會發生相應的變化。這樣就把抽象模型的這兩個方面分離開了, 使得它們可以獨立地改變和複用。

• 如果在更改一個對象的時候, 需要同時連帶改變其他的對象, 而且不知道究竟應該有多少對象需要被連帶改變, 這種情況可以用觀察者模式, 被更改的那一個對象很明顯就相當於是目標對象, 而需要連帶修改的多個其他對象,就作爲多個觀察者對象了。

• 當一個對象必須通知其他的對象, 但是你又希望這個對象和其他被它通知的對象是鬆散耦合的。也就是說這個對象其實不想知道具體被通知的對象。這種情況可以選用觀察者模式,這個對象就相當於是目標對象, 而被它通知的對象就是觀察看對象了。

 

 

13 命令模式(GoF的著作中劃分爲行爲型)

定義:將一個求封裝爲一個對象,從而使你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支持可撤銷的操作。

本質:封裝請求。

使用步驟:【涉及名詞】

Command:定義命令的接口,聲明執行的方法。

ConcreteCommand:命令接口實現對象,是“ 虛” 的實現:通常會持有接收者,並調用接收者的功能來完成命令要執行的操作。

Receiver:接收者,真正執行命令的對象。任何類都可能成爲一個接收者,只要它能夠實現命令要求實現的相應功能。

Invoker:要求命令對象執行請求,通常會持有命令對象,可以持有很多的命令對象。這個是客戶端真正觸發命令並要求命令執行相應操作的地方,也就是說相當於使用命令對象的入口。

Client :創建具體的命令對象,並且設置命令對象的接收者。注意這個不是我們常規意義上的客戶端,而是在組裝命令對象和接收者,或許,把這個Client稱爲裝配者會更好理解,因爲真正使用命令的客戶端是從Invoker來觸發執行。

1.定義命令接口--Command,接口中含有execute()方法2.定義具體的命令ConcreteCommand實現Command接口,持有接收者對象Receiver,以及命令自身狀態state,構造函數以Receiver爲參數,實現execute()方法(其中調用receiver.action())。

3.定義Receiver對象類,提供action方法,真正執行命令的相應操作;

4.定義調用者Invoker對象類,持有Command對象,提供setCommand方法--設置調用者持有的命令對象,提供runCommand()方法,方法中調用command.execute() ;

5.客戶端實現:A.先創建接收者Receiver對象,然後以Receiver爲參數創建CommandB.創建Invoker對象,setCommand

注意這個不是我們通常意義上的測試客戶端.主要功能是要創建命令對並設定它的接收者,因此這裏並沒有調用執行的代碼。

 

優點:更鬆散的耦合;更動態的控制;很自然的複合命令;更好的擴展性。

缺點:---

何時選用:

• 如果需要抽象出需要執行的動作, 並參數化這些對象, 可以選用命令模式。將這些需要執行的動作抽象成爲命令, 然後實現命令的參數化配置。

• 如果需要在不同的時刻指定、排列和執行請求, 可以選用命令模式。將這些請求封裝成爲命令對象, 然後實現將請求隊列化。

• 如果需要支持取消操作, 可以選用命令模式, 通過管理命令對象, 能很容易地實現命令的恢復和重做功能。

• 如果需要支持當系統崩潰時,能將系統的操作功能重新執行一遍, 可以選用命令模式。將這些操作功能的請求封裝成命令對象, 然後實現日誌命令, 就可以在系統恢復以後, 通過日誌獲取命令列衰,從而重新執行一遍功能。

• 在需要事務的系統中, 可以選用命令模式。命令模式提供了對事務進行建模的方法。命令模式有一個別名就是Transaction

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章