古典的オブザーバパターン(メモ)
このデザインの長所は、観察者側も報告者側も相手のクラスの内部設計を把握しなくていいことである。
Model (Data) と View (UI)
- Viewは変更が多い。そのためData側がViewに依存すると脆いし、MVCにも違反することとなる。(ModelがViewに直接依存する)
- その依存性を、具象実装で逆転するような形にするのがObserver。
- Dataが監視される側、Viewが監視する側となり、Dataに変更が加えられたらSubscribeしているViewに通知を送るのが基本スタイル。
Observable と Observer
- Observable (Subject)
- 基本的に、Dataが監視される側なので、Observable
- 登録メソッド名は色々。引数はどれも
(IObserver : observer)
- Subscribe
- Add
- AddObserver
- RegisterObserver
Push と Pull
Observerパターンでは,タイミングの通知を主に置いているため,それ以上の情報を受け渡すには工夫がいります。 この問題に対処するには伝統的にPush, Pullという2つの方法があります。
- Observableの
NotifyObservers()
の中で呼び出すUpdate()
に引数として「変更情報」を付与するか否か。という話。 - Pushの場合は引数付き。Pullの場合は引数なし。というイメージ。
- Pushのデメリット:各Observerの引数の型を一致させる必要がある。
- eventを使う場合、Observableの各プロパティの変更を別々のeventとして登録しておけば一応Observer毎に柔軟に対応できる。event増えるけど
- Pullのデメリット:Observableの内部実装を知る必要がある(データを取りに行く訳だから)
付録:Push vs EventHandler
- 2015/04/14
- (C#)event宣言する際、
Action<T>
使ってたけどやはりEventHandler
使えば型に依存せず綺麗にPush型の通知できるんじゃね?- と思ったけど、無理でした\(^o^)/
- (C#)event宣言する際、
- EventHandler(TEventArgs) デリゲート (System)