2011年7月31日 星期日

《深入淺出 設計模式》筆記

Ch1 介紹設計模式

一.改變是一種常態

1.設計守則(1):找出程式中可能需要更動之處,把它們取出並封裝起來,不要和那些不需要更動的程式碼混在一起


二.抽出變動的部份

1.設計守則(2):寫程式是針對介面而寫,而非針對實踐方式

2.由行為類別實踐行為介面

﹡在設計模式中,所謂的「介面」指的是超型別(supertype),可以是類別或介面的某個方法

三.針對介面寫程式

1.「寫程式是針對介面而寫」的意思是「寫程式是針對超型態(supertype)而寫」,關鍵在多型


四.從大局觀之

1.設計守則(3):多用合成,少用繼承

2.策略模式(Strategy Pattern)<1>:定義了演算法家族,個別封裝起來,讓它們之間可以互相替換,此模式讓演算法的變動,不會影響到使用演算法的程式


五.共通詞彙

1.當你使用模式名稱與他人溝通時,其實還交流了包括模式背後所象徵的內容、特性、限制,設計模式告訴我們如何組織類別和物件,以解決某類型的問題



Ch2 觀察者模式

一.定義觀察者模式

1.觀察者模式(Observer Pattern)<2>:定義了物件之間的一對多關係,如此一來,當一個物件改變狀態,其他相依者都會收到通知並自動被更新

2.在觀察者模式中,會改變的是主題的狀態,以及觀察者的數目與型態


二.鬆綁

1.設計守則(4):盡量讓需要互動的物件之間關係鬆綁



Ch3 裝飾者模式

一.開放關閉守則(The Open Closed Principle (OCP))

1.設計守則(5):類別應該開放,以便擴充;應該關閉,禁止被修改

2.慎選最有可能改變的地方,才使用開放關閉守則


二.定義裝飾者模式

1.裝飾者模式(Decorator Pattern)<3>:動態地將責任加諸於物件上。若要擴充功能,裝飾者提供了比繼承更有彈性的選擇

2.裝飾者和被裝飾者有相同的超型態

3.你可以利用一個或多個裝飾者包裝一個物件

4.裝飾者和被裝飾者有相同的超型態,所以在任何需要原始物件(被裝飾者)的場合,可以用被包裝的物件(裝飾者)取而代之

5.裝飾者可以在被裝飾者的行為,前面或(與)後面加上自己的行為,甚至將被裝飾者的行為整個取代掉,而達到特定的目的

6.物件可以在任何時候被裝飾,所以可以在執行期間動態地用任何合適的裝飾者,來裝飾物件

7.裝飾者會導致程式中出現許多小類別,應謹慎使用

8.不改變介面,但加入了責任



Ch4 工廠模式

一.定義工廠方法模型

1.工廠方法模式(Factory Pattern)<4>:定義了一個建立物件的介面,但由次類別決定要實體化的類別為何者

2.工廠方法讓類別把實體化的動作,交由次類別進行

3.工廠方法模式讓次類別決定該建立的物件為何,據此達到將物件建立的過程封裝的目的
﹡「決定」並不是指模式允許次類別本身在執行期做決定,而是指:在撰寫建立者類別時,不需要知道實際建立的產品是何者。選擇使用哪個次類別,自然就決定了實際建立的產品為何


二.顛覆依賴守則(dependency Inversion Principle)

1.設計守則(7):依賴抽象類別,不要依賴具象類別

2.當直接實體化一個物件,就是在依賴它的具象類別

3.不應讓高階元件依賴於低階元件,而且,不論高階或低階元件,「兩者」都應相依於抽象類別

4.變數不可以持有具象類別的參考。如果使用new,就會持有具象類別的參考。改用工廠模式避開這樣的作法

5.不要讓類別繼承來自具象類別。如果繼承自具象類別,就會依賴具象類別。因此應繼承自一個抽象(介面或抽象類別)

6.不要讓次類別中的方法覆寫超類別中的方法。如果覆寫超類別的實踐方法,那麼超類別就不是一個真正適合被繼承的抽象。超類別中所實踐的方法,應該由所有的次類別共享


三.定義抽象工廠模式

1.抽象工廠模式(Abstract Factory Pattern)<5>:提供了一個介面,建立相關或相依物件的家族,而不需要明確指定具象類別

2.抽象工廠的任務是定義一個介面,而這個介面負責建立一組產品。這個介面內的每個方法,負責建立一個抽象產品,同時利用實踐抽象工廠的次類別,提供這些具體作法


四.模式的比較

1.工廠方法使用的是類別抽象工廠使用的是物件

2.工廠方法使用繼承來建立物件;抽象工廠是藉由物件的合成來建立物件

3.利用工廠方法建立物件,需要繼承一個類別,並覆寫它的工廠方法,而這個工廠方法就是用來建立物件的

4.整個工廠方法模式,不外乎就是藉由繼承來的次類別建立物件。這種作法,客戶只需要知道他們所使用的抽象型態,而由次類別負責決定具象型態。換句話說,工廠方法只負責將客戶從具象型態中鬆綁

5.抽象工廠提供一個抽象型態,用來建立一個產品家族。這個型態的次類別定義了產品被產生的方法。欲使用這個工廠,必須先實體化一個工廠,然後將它傳進一些針對抽象型態所寫程式碼。所以,抽象工廠也能將客戶從具象型態中鬆綁

6.抽象工廠的另一優點,是可以將一群相關的產品集結起來

7.使用抽象工廠若要擴充相關的產品,則必須改變介面

8.若目前不知道將來需要實體化哪些具象類別時,可使用工廠方法

9.由每個次類別「決定」實體化哪個「具象類別」

10.所有的工廠都是用來封裝物件的建立

11.工廠方法允許類別將實體化的動作,交由次類別進行

12.抽象工廠建立相關的物件家族,而不需要依賴它們的具象類別



Ch5 獨體模式

一.定義獨體模式

1.獨體模式(Singleton Pattern)<6>:確保一個類別只有一個實體,並給它一個存取的全域點(global point)

2.獨體的建構式宣告為private

3.欲取得獨體的實體,不能自行實體化一個實體,而須呼叫getInstance()

4.同步化getInstance()的方法雖然簡單又有效,但同步化一個方法,可能造成程式的執行效率驟降。因此別把getInstance()放在頻繁運作的地方

5.如果應用程式總是建立並使用獨體;或者將獨體建立在前,而在執行期沒有太大的負擔狀況下,可以使用率先(eagerly)建立此獨體

6.若要減少使用同步化,可利用雙重檢查上鎖(double-checked locking)。首先檢查實體是否已經建立,若尚未建立,「才」進行同步化。如此一來,只有第一次會同步化

7.率先實體化會比拖延實體化更浪費資源

8.每個類別載入者(class loader)都定義了自己的命名空間,如果有兩個以上的類別載入者,不同的類別載入者可能會載入同一個類別,若發生在獨體上,則會導致產生多個實體。如果你的程式有多個類別載入者並使用獨體模式,你應自行指定類別載入者,並指定同一個類別載入者



Ch6 命令模式

一.定義命令模式

1.命令模式(Command Pattern)<7>:將「請求」封裝成物件,以便使用不同的請求、佇列或者日誌,參數化其他物件

2.命令模式支援可復原的作業。做法是實踐一個undo()方法,來回到execute()被執行前的狀態

3.命令物件中記錄著某個接收者的一組動作。要達到這一點,將動作和接收者包進物件中,指暴露出一個execute()方法,當呼叫此方法時,接收者就會進行這些動作

4.命令模式也能支援Meta Command Pattern。Meta Command Pattern可建立命令的巨集,以便一次執行多個命令

5.命令模式將發出請求的物件和執行請求的物件之間鬆綁

6.在被鬆綁的兩者之間,是藉由命令物件進行溝通

7.調用者可以接受命令當作參數,甚至在執行期動態地進行


二.空物件

1.若需要一個沒有任何意義的值時,則可設為noCommand


三.巨集命令

1.巨集命令允許調用多個方法。巨集也可支援復原

2.若要實踐多層次的復原操作,則不要只是記錄最後一個被執行的命令,而是使用一個堆疊記錄操作過程的每一個命令

3.實務上,通常是直接實踐了請求,而不是將工作交由接收者進行


四.佇列請求

1.命列可以將運算包裝起來(一個接收者和一組動作),然後將它傳來傳去,就像是一般的物件一樣。即使在命令物件被建立許久之後,運算依然可以被調用

2.只要是實踐命列模式的物件,就可以放入佇列裡,當執行緒可用時,救定用此物件的execute()方法


五.日誌請求

1.藉由新增store()、load()兩個方法,可支援日誌的記錄

2.在Java中,我們可以利用物件的序列化(Serialization)實踐這些方法,但一般認為序列化最好還是只用在物件的存續(persistance)



Ch7 轉接器模式

一.定義轉接器模式

1.轉接器模式(Adapter Pattern)<8>:將一個類別的介面,轉換成另一個介面以供客戶使用

2.被轉接者的任何次類別,都可以搭配轉接器使用

3.若介面轉換後,想要改變介面,轉接器可以將改變的部份封裝起來,已因應不同的介面

4.當需要使用一個既有的類別,而其介面並不符合你的需求時,就使用轉接器



Ch8 表象模式

一.定義表象模式

1.提供了一個統一的介面,用來存取次系統中的一群介面。表象定義了一個較高層次的介面,讓次系統更容易使用

2.表象提供簡化介面的同時,依然將系統完整的功能暴露出來,以供需要的人使用

3.表象不只簡化了介面,也將客戶從元件的次系統中鬆綁出來

4.表象與轉接器兩種模式的差異,在於目的:轉接器模式的目的是,改變介面符合客戶的期望;表象模式的目的是,提供次系統的一個簡化界面

5.當需要簡化並統一一個大很大的介面,或一群複雜的介面,就使用表象

6.轉接器將一個物件包裝起來以改變其介面;裝飾者將一個物件包裝起來以增加新的行為和責任;表象將一群物件「包裝」起來以簡化其介面


二.極少化守則(Least Knowledge Principle 或 Law of Demeter)

1.設計守則(8):只和你的密友談話

2.當你正在設計一個系統,不管是任何物件,都要注意它所互動的類別有哪些,並注意它和這些類別如何互動

3.依據此守則,以某個物件而言,此物件的方法定義內,只應引用物件的某些方法,這些方法必須屬於:
(1)該物件本身
(2)被當作方法的參數而傳遞進來的物件
(3)此方法所建立或實體化的任何物件
(4)物件的任何元件

4.雖然此守則減少了物件之間的依賴程度,但也可能導致更多的「包裝」類別被製造出來,以處理和其他物件的溝通,使得複雜度增加與降低執行期的效率



Ch9 樣板方法模式

一.定義樣板方法模式

1.樣板方法模式(Template Method Pattern)<9>:將一個演算法的骨架定義在一個方法中,而演算法本身會用到的一些方法,則是定義在次類別中

2.樣板方法讓次類別在不改變演算法架構的情況下,重新定義演算法中的某些步驟

3.樣板方法定義了一個演算法的步驟,並允許次類別為一個或多個步驟,提供其實踐方式

4.樣板就是一個方法;更具體地說,這個方法將演算法定義成一組步驟。其中的任何步驟都可以是抽象方法,而由次類別負責實踐這些抽象方法。這可以確保演算法的結構維持不變,同時由次類別提供部份實踐方式

5.策略模式與樣版方法模式都是用來封裝演算法。策略模式是用合成;樣板方法模式是用繼承


二.實踐掛鉤

1.掛鉤(hook)是一種方法,被宣告在抽象類別中,而且定義為「什麼都不做」,或是有預設的實踐方式。掛鉤的存在,可以讓次類別有能力對演算法進行掛鉤。要不要掛鉤,由次類別自行決定是否實踐

2.想要使用掛鉤,則必須在次類別中覆寫預設的定義

3.當你的次類別「必須」提供演算法用在某個方法或步驟的實踐時,就使用抽象方法

4.如果演算法的這個部份是選擇性的,就用掛鉤。如果是掛鉤的話,次類別可以選擇實踐這個掛鉤,但並不強制這麼做

5.掛鉤可以讓次類別實踐演算法中選擇性的部份,或者在掛鉤對於次類別的實踐並不重要的時候,次類別可以對此掛鉤置之不理

6.掛鉤的另一使用實機,是讓次類別能夠有機會對於樣板方法中某個即將發生(或剛剛發生)的步驟作出反應

7.每一個具象的次類別,都必須對所有的抽象方法提供完整的實踐,否則樣板方法中的演算法就無法正常運作

8.有些步驟是選擇性的,所以你可以將這些步驟實踐成掛鉤,而不是將它們實踐成抽象方法,如此可以讓次類別的負荷減輕些


二.好萊塢守則(Hollywood Principle)

1.設計守則(9):別呼叫我們,我們會呼叫你

2.好萊塢守則使我們防止「依賴腐敗」。當高階元件依賴低階元件,而低階元件又依賴高階元件,而高階元件又依賴邊側元件,而邊側元件又依賴低階元件時,你就有了依賴腐敗的情況。沒有人可以輕易地搞懂系統是如何設計的

3.在此守則下,我們允許低階元件將自己掛鉤到系統上,但是高階元件會決定何時用到這些低階元件,並決定要如何使用這些低階元件。換句話說,高階元件對於低階元件的對待方式是「別呼叫我們,我們會呼叫你」

4.顛覆依賴守則教我們盡量避免使用具象類別,而多使用抽象;而好萊塢守則是用在建立框架或元件,好讓低階元件能夠被掛鉤進入系統中,而且又不會讓高階元件依賴低階元件。兩者的目標都在於鬆綁,但是顛覆依賴守則堅持於如何在設計中避免相依性

5.低階元件在結束時,常常會呼叫從超類別中繼承來的方法。我們所要做的是,避免讓高階和低階元件之間有明顯的相互依賴(也就是高階元件依賴低階元件,同時低階元件依賴高階元件)


三.繪圖的掛鉤

1.具象的applet使用許多掛鉤以提供行為。因為這些行為是用掛鉤實踐的,所以Applet類別就不用去實踐它們



Ch10 反覆器與合成模式

一.定義反覆器模式

1.反覆器模式(Iterator Pattern)<10>:讓我們能夠取得一個聚集內的每一個元素,而不需要此聚集將其實踐方式暴露出來

2.反覆器負責在元素之間遊走,而不是由聚集在元素之間遊走。這讓聚集的介面以及聚集的實踐變得更簡潔,也讓責任更清楚

3.當我們寫了一個方法,此方法需要以反覆器當作參數時,其實就是在使用多型反覆動作。也就是說,我們所寫出的程式碼,可以在不同的聚合中遊走,只要這個聚合支援反覆器即可。我們不在乎這個聚合是如何被實踐的,但依然可以寫程式在它內部的元素之間遊走

4.如果你需要在反覆器介面為你的聚合新增功能,你可以隨時擴充反覆器介面

5.反覆器允許存取聚集內的元素,而不需要它暴露出內部的結構

6.反覆器將反覆遊走的動作封裝入一個物件中


二.單一責任守則

1.設計守則(10):一個類別應該只具有一個改變的理由

2.類別的每個責任都有改變的淺在部份。超過一個責任,就代表超過一個改變的淺在部份

3.盡量讓每個類別保持單一責任


Ch11 合成模式

一.定義合成模式

1.合成模式(Composite Pattern)<11>:允許你將物件合成樹狀結構,樹裡面包含了合成以及個別的物件,呈現「部份/整體」的階層關係

2.合成能讓客戶程式碼以一致的方式處理個別物件,以及合成的物件。換句話說,在大多數情況下,我們可以忽略合成以及個別物件之間的差異

3.合成模式以單一責任的設計守則,換取透明性(transparency)。透明性是讓元件的介面同時包含一些管理子節點的操作以及葉節點的操作,如此以來,客戶就可以將合成節點和葉節點一視同仁;也就是說,一個元素究竟是合成節點或者是葉節點,客戶看不到

4.為確保透明性,合成內所有的物件都必須實踐相同的介面,否則客戶就必須擔心哪個物件是用哪個介面,這樣就失去何模式的意義。若要解決這樣的問題,可以讓這樣的方法不做事,或者傳回null值或false,甚至是丟出例外

5.有時候,如果這個合成的架構太過於複雜,或者在其間遊走的代價太高,那麼實踐合成節點的快取就有很大的效益。比方說,如果你經常在一個合成內遊走,而且每一個子節點都需要進行某些計算,得到一個複雜的計算結果,你就應該使用快取將結果值真實地記錄下來,省去一再遊走所造成的資源浪費



Ch12 狀態模式

一.定義狀態模式

1.狀態模式(State Pattern)<12>:允許物件隨著內在的狀態而改變行為,好像物件的類別改變了一樣

2.這個模式將狀態封裝成為獨立的類別,並將動作轉介到目前的狀態,我們知道行為會隨著內部的狀態而改變

3.將狀態轉換放在狀態類別中,會造成狀態類別之間產生了依賴性

4.若要共用狀態物件,必須將每個狀態指定到靜態的實體變數中。此外,你得先確認你的狀態物件沒有持有它們自己的內部狀態,否則就不能共用

5.在個別的狀態類別中封裝狀態行為,結果總是增加這個設計中的類別數目,這是為了要獲取彈性而付出的代價,但除非你的程式碼是能用完就丟,否則這樣的狀態模式設計是絕對值得的。其實真正重要的是,你暴露給客戶的類別數目,在狀態模式的設計中,可以將這些狀態類別全都隱藏起來

6.如果你有一個系統,它有很多的狀態,但是你決定不將這些狀態封裝在不同的物件中,那麼就有很多很大的條件敘述,這會讓你的程式碼不容易維護也不容易閱讀。藉由使用許多物件,可以讓狀態變得乾淨

7.如果我們沒有共同的功能可以放進抽象類別中,就會使用介面。在你實踐狀態模式時,很可能想使用抽象類別,這麼一來,當你以後需要在抽象類別中加入新的方法,就會很容易,不需要打破具象狀態的封裝

8.狀態模式將各個狀態都變成了類別

9.Context會將行為委派到目前狀態中

10.藉由將每個狀態都封裝成各自的物件,以後任何改變的需求都將只會影響局部

11.策略模式通常會主動指定Context類別該具備什麼行為或演算法

12.狀態模式允許Context隨著狀態的改變而改變行為

13.狀態轉換可以由狀態類別或是Context類別控制

14.狀態類別可以被多個Context實體所共用



Ch13 代理人模式

一.定義代理人模式

1.代理人模式(Proxy Pattern)<13>:讓某個物件具有一個替身,藉以控制外界對此物件的接觸

2.使用代理人模式建立代表物件,讓代表物件控制某物件的存取,被代理的物件可以是遠端的物件、建立成本高的物件、或者需要安全控管的物件

3.若要讓客戶使用代理人,而非使用真正的物件,可提供一個工廠,傳出一個物件。因為物件的建立是在工廠方法內發生的,我們可以傳出一個代理人,而不是傳出真正的服務物件

4.代理人和轉接器都是位居客戶和真正的物件之間,並負責將請求轉給真正的物件。轉接器會改變物件的介面,但是代理人則實踐相同的介面

5.裝飾者模式為物件加上行為,而代理人則是控制存取


二.代理人動物園

1.遠端代理人(Remote Proxy):管理客戶和遠端物件之間的互動

2.虛擬代理人(Virtual Proxy):控制存取建立成本昂貴的資源

3.保護代理人(Protection Proxy):根據權限控制對資源的存取。可根據客戶的角色,決定允許或不允許客戶存取特定的方法,所以保護代理人可能只提供給客戶部份的介面

4.備用代理人(Caching Proxy):會將之前的物件記錄下來,並暫存起來,以供後續使用,減少計算或網路成本

5.防火牆代理人(Firewall Proxy):控制網路資源的存取,保護內部免於受到外面的傷害

6.聰明參考代理人(Smart Reference Proxy):當物件被參考到時,會進行額外的動作,例如計算此物件被參考的次數

7.同步化代理人(Synchronization Proxy):提供安全的存取,讓多個執行緒存取同一個物件,不會出差錯

8.隱藏複雜代理人(Complexity Hiding Proxy):用來對一群複雜的類別,進行複雜度隱藏以及存取控制。有時也稱表象代理人(Facade Proxy)。隱藏複雜代理人與表象模式並不一樣,因為代理人是控制存取,而表象模式只提供另一組介面

9.寫入時才複製的代理人(Copy-On-Write Proxy):用來控制物件的複製,將複製的動作拖延進行,直到客戶真的需要為止。這是虛擬代理人的變形



Ch14 複合模式

一.定義複合模式

1.複合模式(Compound Pattern)<14>:結合兩個或以上的模式,組成一個新的解決方案,可以解決一再發生的一般性問題


二.Model-View-Controller(MVC)

1.MVC是複合模式,結合了觀察者模式、策略模式、合成模式

2.model使用觀察者模式,可以讓觀察者保持對model狀態的掌握,且兩者之間依然鬆綁

3.controller是view的策略,view可以使用不同的controller,得到不同的行為

4.view使用合成模式,將許多使用者介面控件組織起來

5.轉接器模式常將model轉接成另一個model,以符合某個既有的view和controller



Ch15 與設計模式相處

一.定義設計模式

1.設計模式(Design Pattern)<15>:在某「情境」(context)下,針對某「問題」的某種「解決方案」

2.情境:採取某個模式的狀況

3.問題:你想在某情境下達到的目標,但也可以是某種情境下的限制

4.解決方案:一個一般性的設計,用來解決限制、達到目標

5.如果你發現處於某個情境下,面對著一群限制的問題,正影響著所欲達成的目標,然而,你能夠採用某個設計,克服這些限制並達到該目標,將你領向某個解決方案。這就是設計模式


二.使用模式型錄

1.意圖(Intent):簡短地描述該模式的作用。也可以把它想成是模式的定義

2.動機(Motivation):具體地描述問題以及如何解決這個問題

3.適用性(Applicability):負責敘述此模式適合在哪些狀況下被採用

4.結構(Structure):提供了圖示,顯示出參與此模式的所有類別之間的關係

5.參與者(Participants):描述在此設計中所牽涉到的類別和物件,其責任和角色為何

6.合作(Collaborations):告訴我們參與者如何在此模式中互相支援

7.後果(Consquences):描述採用此模式之後可能有的效果:好的與不好的

8.實踐(Implementation):提供了你所需要使用的技巧,以及你應該小心面對的問題

9.範例程式(Sample Code):提供程式碼的片段

10.已知用途(Known Uses):用來描述在真實的系統中,有哪些運用此模式的實際例子

11.相關的模式(Related Patterns):描述了此模式和其他模式之間的關係


三.定義反模式

1.反模式(Anti-Pattern)<16>:告訴你如何採用一個不好的解決方案解決一個問題

2.反模式告訴我們為什麼不好的解決方案會有吸引力

3.反模式告訴你為何這個解決方案長遠以後會造成不好的影響

4.反模式建議你改用其他的模式,提供更好的解決方案

5.反模式看起來總像是一個好的解決方案,但當它真正被採用後,就會帶來麻煩



Ch16 剩下的模式

一.橋樑模式

1.橋樑模式(Bridge Pattern)<17>:不只改變你的實踐方法,也能改變你的抽象

2.橋樑模式採取的作法是,將實踐和抽象放在兩個不同的類別階層中

3.橋樑的用途:
(1)適合使用在需要跨越多個平台的圖形和視窗系統上
(2)當你需要使用不同的方式改變介面以及實踐時,可以使用它

4.橋樑的優點:
(1)將實踐予以鬆綁,讓它和介面之間不再是永恆的關係
(2)抽象和實踐各自被擴充,不會影響到對方
(3)對於「具象的抽象類別」所做的改變,不會影響到客戶

5.橋樑的缺點:
(1)增加複雜度


二.建立者模式

1.建立者模式(Builder Pattern)<18>:封裝一個產品的建構過程,並允許可依照步驟建構

2.建立者的用途:
(1)用於建立合成結構

3.建立者的優點:
(1)將一個複雜物件的建立過程封裝起來
(2)允許物件在多個步驟建立,並且可以改變程序(這和只有一個步驟的工廠方法不同)
(3)將產品內部的表現方式隱藏起來,但客戶無法觸及
(4)產品的實踐方式可以被替換,因為客戶只看到抽象的介面

4.建立者的缺點:
(1)和工廠模式相較,採用建立者模式建立物件的客戶,需要具備更多的特定領域知識


三.責任鏈模式

1.責任鏈模式(Chain of Responsibility Pattern)<19>:讓一個以上的物件,有機會能夠處理某個請求

2.透過責任鏈模式,你可以對某個請求感興趣的物件建立成一個鏈結,每個物件依序檢視此請求,並處理之,或者是將它傳給鏈結中的下移物件

3.責任鏈的用途:
(1)經常被使用在視窗系統中,處理像是滑鼠和鍵盤的事件

4.責任鏈的優點:
(1)將請求的發出者和接受者之間予以鬆綁
(2)可以簡化你的物件,因為它不需要知道此鏈結的結構
(3)允許動態地新增或刪除責任,你可以改變鏈結內的某個處理程式,或者調動它們的順序

5.責任鏈的缺點:
(1)並不保證請求一定會被執行;如果沒有任何物件處理它的話,可能會落到鏈結尾端之外(這可以是優點也可以是缺點)
(2)可能不容易觀察執行期的行為,有礙於除錯


四.蠅量級模式

1.蠅量級模式(Flyweight Pattern)<20>:讓某個類別的一個實體,能夠提供許多「虛擬實體」

2.蠅量級的用途:
(1)當一個類別有許多的實體,而這些實體能夠被用一致的方法控制的時候,就可以使用蠅量級模式

3.蠅量級的優點:
(1)大幅縮減執行期物件的個數,節省記憶體
(2)將許多「虛擬」物件的狀態集中管理

4.蠅量級的缺點
(1)一旦你實踐了它,那麼所有的邏輯實體,將無法擁有獨立而不同的行為


五.翻譯者模式

1.翻譯者模式(Interpreter Pattern)<21>:為語言建立翻譯者

2.每個文法規則都用一個類別代表。類別直接對應到文法

3.翻譯者的用途:
(1)當你需要實踐一個簡單的語言時
(2)當你有一個簡單的文法,而且簡單比效率來的重要時
(3)可以處理編劇語言,以及編程語言

4.翻譯者的優點:
(1)將每一個文法規則設計成一個類別,方便於實踐語言
(2)因為文法就是許多類別的集合,所以你可以輕易地改變並擴充此語言
(3)藉由在類別結構中加入新的方法,可以在翻譯者的同時增加新的行為,例如輸出格式的美化,或者進行複雜的程式檢查

5.翻譯者的缺點:
(1)當文法規則的數目太大的時候,就會變得非常複雜。在這種情況下,你可以使用剖析器/編譯器的產生器會更適合


六.居間協調者模式

1.居間協調者模式(Mediator Pattern)<22>:將相關物件之間的複雜溝通和控制方式予以簡化

2.每個物件都會在自己的狀態改變時,通知居間協調者

3.每個物件都會對居間協調者所發出的請求做出回應

4.居間協調者內包含了整個系統的控制邏輯。當某一個裝置需要一個新的規格時,或者是一個新的裝置被加入到此系統內,所有需要用到的邏輯,也都會被加進居間協調者

5.居間協調者的用途:
(1)常用來協調相關的GUI元件

6.居間協調者的優點:
(1)藉由將物件彼此鬆綁,可以增加物件的再利用性
(2)藉由將控制邏輯中央集權化,可以簡化系統維護
(3)可以讓物件之間所傳遞的訊息,變得簡單而且大幅減少

7.居間協調者的缺點:
(1)如果涉及不當的話,居間協調者本身會變得過於複雜


七.助記物模式

1.助記物模式(Memento Pattern)<23>:讓物件返回之間的狀態(例如,當你的使用者發出「復原」的請求)

2.助記物模式的兩個目標:
(1)儲存系統關鍵物件的狀態
(2)維護關鍵物件的封裝

3.助記物的用途:
(1)助記物是儲存狀態

4.助記物的優點:
(1)將被儲存的狀態放在外面,不要和關鍵物件混在一起,這可以幫助維護內聚力
(2)讓關鍵物件的資料封裝不受破壞
(3)提供了容易實踐的恢復能力

5.助記物的缺點:
(1)儲存和回復狀態的過程,可能相當耗費時間
(2)其實可以使用序列化機制儲存系統的狀態


八.雛型模式

1.雛型模式(Prototype Pattern)<24>:簡化建立物件實體的過程

2.這個模式的重點在於,客戶的程式碼在不知道特定類別為何的情況之下,可以製造出新的實體

3.雛型的用途:
(1)在一個複雜的類別階層架構中,當系統必須從其中的許多類別產生實體化的物件時

4.雛型的優點:
(1)將製造新實體過程中複雜的一切隱藏起來,讓客戶無須面對這一切
(2)讓客戶能夠產生未知類別的實體
(3)在某些環境下,複製物件比建立物件更有效率

5.雛型的缺點:
(1)物件的複製過程有時候相當複雜


九.參觀者模式

1.參觀者模式(Visitor Pattern)<25>:定義了一種一對多的依賴關聯、架構設計

2.參觀者必須參觀合成內的每個元素;這樣的功能是在旅遊者(Traverser)物件中,參觀者藉由旅遊者的引導,收集合成中所有物件的狀態。一旦狀態被收集了,客戶就可以讓參觀者對狀態進行各種操作。當需要新的功能時,只要加強參觀者即可

3.參觀者的用途:
(1)當你想要為一個合成增加新的能力,且封裝並不重要時

3.參觀者的優點:
(1)允許你對合成結構加入新的操作,而無須改變結構本身
(2)當想要加入新的操作時,會相當的容易
(3)參觀者所進行的操作,其程式碼是集中在一起的

4.參觀者的缺點:
(1)會打破合成類別的封裝
(2)因為旅遊的功能牽涉其中,所以對合成結構得改變就更加困難

沒有留言:

張貼留言