Composite Pattern
看了這個影片,我終於懂了這個composite pattern在幹嘛了 @@原來就是把fractal (碎形) 應用在software construnction中。
composite pattern其實就是一個tree structure,每個node (包含leaf)都是某個type,透過implementing某個interface,或是繼承某個super class:
non-leaf node就是另一個 subtree,由同樣type的nodes組成,所以這不就是fractal嗎???
不過這邊需要語言支援polymorphism,也就是在runtime時候,同樣的interface能流向不同sublcass定義的implementation。
composite pattern好處是,我們不用type-checking! 完全依賴polymorphism幫我們做事,而且建構簡單,整體邏輯性都很清楚。
舉例來說,我們定義一個interface讓所有"建築"都必須要遵從:
某個叫做"Housing"的subclass就是一個non-leaf node,因為他也可以由其他 IStructure type objects 組成 (composite of):
可以看到這個Housing class還有一個collection of other IStructures,因為它是一個Composite node,不是lead node,也就是這個Housing建築體是由其他IStructure建築體組成的:
如果是leaf node的話,定義為不由其他IStructure建築體組成,所以只要單純implement IStructure interface就好:
結論: 如果建構一個東西,是有fractal特性的話,那就使用composite pattern,不過這需要語言有polymorphism支援,應該所有的OOP都有吧,因為那是OOP的根本元素。
Proxy Pattern
某個class A的代理人或是替身稱為proxy,為何要使用proxy呢?1. 耗運算或是硬體資源的物件,可以有個lightweight self / or cache當作替身
2. 防護性,讓外界接觸不到真正的物件 (讓子彈飛之黃四郎?!?!)
3. 遠端物件的local替身,這其實跟第一點也差不多
4. 當作任務dispatcher,implement額外的功能,分配給適當的A instances
這邊比較有趣的是,proxy是某個class A的替身(藉由讓兩者都implement一樣的interface,但是A是proxy的delegate,因為真正執行proxy的功能是要給A去做:
Decorator Pattern
這主要是要解決怎麼在runtime增加一個class的功能的難題。如果利用subclass / extension (swift / kotlin),則是在compile time才有辦法定義。所以這邊的邏輯就是“利用aggregation取代subclassing“。藉由層層reference,下圖中C "has a" B,而B "has a" A,stack上層物件能增益其包含物件的功能:
注意A B C是同一個type (藉由implement 同一個interface)。
Decorator pattern要用實際例子來解釋比較容易懂。假設一個網頁的該有的基本interface如
下:
現在我們想要runtime“增益augment"這個BasicWebPage class,讓他變成更多功能的網頁,我們需要一個abstract Decorator class,也implement了網頁必有的interface:
所以這個decorator是一個“網頁”(因為有implement WebPage interface),他的concrete subclass instance當然也是一個"網頁",所以只要這個subclass定義某個額外的功能(例如驗證身份),就擴增了網頁instance 的能力(變成可以驗證身份的網頁)。
注意這個Decorator的有包含basic功能的WebPage,所以就像前面stack A B C圖示所說,這是一個aggregation。
另外注意這些decorator instances的display()透過呼叫了super.display(),層層往下傳到basic BasicWebPage class的display(),這是合乎設計初衷的,因為非擴充的功能應該要使用最原始的stack最下層的implementation。
以下是UML diagram:
至於client要怎麼使用Decorator pattern才能runtime擴增功能呢?
1. 我們先建立了一個BasicWebPage instance,
2. 然後製作一個decorator AuthorizedWebPage instance去stack在 BasicWebPage上面,
3. 然後在stack AuthenticatedWebPage instance去stack在 AuthorizedWebPage上面
4. 由於這三個class都有implement WebPage interface,所以可以用同一個object reference指向這三個instance
5. 在呼叫display的時候,AuthenticatedWebPage instance先往下一直到底呼叫了 BasicWebPage implement的display(),這就是最基本的功能,然後往上return時,又由下而上層層執行了每個擴增instance所implement的display(),這樣就完成了Decorator的架構實現。
用Decorator的好處就是不用implement各種擴充功能的排列組合所可能需要的subclasses,而是直接stack各種功能就好。
沒有留言:
張貼留言