Re: [問題] 不懂observer pattern觀察者模式的好處?

作者: qrtt1 (有些事,有時候。。。)   2017-04-08 10:56:11
※ 引述《naticom (踢踢~)》之銘言:
: 最近開始看一些有關於design pattern的東西,感覺都不是很直覺會想出的方法
: Observer pattern 在講解的時候,幾乎大家都拿訂閱報紙當例子
: https://dotblogs.com.tw/joysdw12/archive/2013/03/13/96531.aspx
: 例如這篇網誌
: 但我真的不太懂為什麼要用一個什麼oberver pattern拿來做這種事情比較好?
: 直觀來說,我們建立一個報社class,裡面有個array儲存所有的讀者
: SubscribeNewspaper()
: UnsubscribeNewspaper()
: SendNewspaper()
: 都是這個報社class的member function
: 讀者class提供update() function
: SubscribeNewspaper()基本上把新的讀者加入array
: UnsubscribeNewspaper()把讀者踢出array
: SendNewspaper()依序traverse array中的讀者,並且呼叫讀者的update()
: 為什麼要拐個彎搞出個介面呢?
: 還請前輩們指教,是不是我OO觀念太薄弱造成的orz
你這個只是『實作』細節,在精神上是沒什麼不一致的。
直接貼 Design Patterns 書上的 Intent
Intent
Define a one-to-many dependency
between objects so that
when one object changes state,
all its dependents are notified and updated automatically.
書上是用 GUI 程式當例子,一個 subject 變了,相關的元件都做出反應
例如數值的值會變,line bar 的長度會變。
把例子換成報紙訂閱不是不行,只是一般人對報紙的用法有既定印像
造成生理上無法接受他的說例。
回到原始的 subject 與 observers 的關係,
subject 是被訂閱的對象,而 observers 是對 subject 的改變有興趣的對象。
若先不考慮 observer pattern,比較沒經驗的功程師可能會寫成這樣:
target1.method9487(subject.a);
if(subject.b) { target2.methodC8763(subject.c); }
target3.methodX(subject);
這例子是表示,你的程式邏輯『緊密地』
讓 subject 與要做反應的 targets 綁在一起,
也就是所謂的 coupling。
要鬆綁這個關係,就要透過『導入間接層』來隔開,
也就是抽象化與一般化,實作上就會用 interface 或抽象類別、方法。
會把它重構成:
1. 所有的 target 都繼成某一個 interface X
2. 所有直接的 method call 都使用通一的名字
3. 為了避免直接、零散地傳遞參數,使用 param object 代替
interface X {
methodX(Param p)
}
所以,重新改寫後,會變成
target1.methodX(subject);
target2.methodX(subject);
target3.methodX(subject);
那,因為所有產生關係的 target 都有同樣介面了,
可以再把成簡化至 collection 內,例如:
X[] targets = {target1, target2, target3};
只要這樣子更新就行了
for (X target: targets) {
target.methodX(subject);
}
對 subject 來說,它就不用特別『關照』個別的 target 需要某個欄位
或某個狀態下才作用,只要通知他們有改變就行了。
然後,再把呼叫的對象 target 換成 observer 就是模式定義的型式
他們達到彼此的實作細節不互相影響,例如原本的:
這條件本來不是在 target2 內部,它現在被推回去 target2 內了:
if(subject.b) { target2.method2(subject.c); }
target2 methodX(subject) {
if(subject.b) {
methodC8763(subject.c)
}
}
你不用擔心改 subject 而弄壞 target2,
也不用擔心改 target2 需要連帶修改 subject 內實作的條件
針對 subject 提供 attach, detach
interface X 改名 Observer 與把 methodX 換成 notify
完成重構後,
你的工作成果就跟 observer pattern 87% 像了。
其實 design pattern 就是由實際工作經驗粹取出來的精華,
不能只看它的結構,而是它要表達的 Intent 得抓住
(不然,有好多張長得差不多的 pattern 怎麼分得出它的異同!?)
作者: johnny94 (32767)   2017-04-08 12:15:00
寫的真好,推推
作者: eieio (好多目標)   2017-04-08 13:23:00
作者: naticom (踢踢~)   2017-04-08 14:00:00
謝謝,寫得真是好
作者: v9290026 (CH)   2017-04-10 18:51:00
受教了

Links booklink

Contact Us: admin [ a t ] ucptt.com