code

2017年11月7日 星期二

Design Patterns 2 - Structural Patterns (Facade / Adapter)

Facade Pattern

facade的中文是"建築物正面",在軟體系統中代表進入某個subsystem的入口,所以使用facade pattern主要是在一個大型複雜的系統中,提供每個subsystem一個"店面入口",但是把店的整個複雜度都隱藏起來。

算是一個中間wrapper class,client透過此facade class來使用subsystem。

未使用facade的client,可能需要分別跟所有subsystems (存款 / 支票 / 提款)打交道:



如果把這些subsystems統一包覆在某個 facade BankService:



其實facade應該是鰻直覺的,多數人即便沒學過facade應該直覺會再包一層,不會讓人直接面對subsystems,因為同理心想像自己是client programmer的時候,應該會瘋掉吧。

注意對不同subsystems來說,他們都需要implement一個IAccount interface,這主要是讓facade class與subsystems溝通用,也就是facade class也不需要知道subsystems的specific implementation:


再來就是facade class的定義。實務上,subsystems有很多功能,facade class可以選擇性包裹要那些功能給client看到就好:



client code就是乖乖使用facade export出來的functionalities,完全不會直接跟subsystems打交道:


優點
1. information hiding: 把subsystem相關資訊隱藏起來
2. decoupling: client code跟subsystem implementation無關
3. simplified interaction: client code不需要跟複雜的subsystems打交道


Adapter Pattern (轉接器)

ps2 轉 usb 的轉接器就是一個adapter。
在軟體工程上,兩個system之間的input/output可能缺乏可以溝通的介面,例如型態不同的問題。簡單來說,adapter pattern就是一個中間翻譯的腳色,讓client能透過target interface介面與提供資源存取的adaptee溝通:



舉例來說:WebClient想要存取WebService,但是不能接受Json格式,此時就需要一個WebAdapter class去implement WebRequester interface,讓WebClient能透過此interface 存取WebService:



WebRequester interface可能長這樣:

WebAdapter部分,可以看到它implement了target interface:



Client部分,使用了target interface:



整個program長這樣:


可以看到client根本不需要知道adaptee (service)是什麼,他只在乎adapter能否讓他透過target interface得到他想要的服務。Adapter基本上就是把adaptee包覆起來,是一個wrapper class

所以adapter class主要用在當我們沒有權力改變adaptee的interface的時候(通常這都是第三方的library或是REST API),並且也不想改變我們自己(client)的interface的時候,因為通常我們自己的interface也被其他人或是subsystems使用,改變會造成連鎖的改變需要。


沒有留言:

張貼留言