1)事前の登録:addObserver

まず、Subject の状態に依存して変化する、すべての Observer を登録します。

# Observer_gof.py
class ExObserver(EasyWindow, Observer):
def __init__(self, subject, **args):
EasyWindow.__init__(self, **args)
subject.addObserver(self)

subject に対して、自身 self を登録 addObserver します。すると、subject の状態が変化したときに、ExObserver の傘下にあるインスタンス self は、その通知を受けられます。

# Observer_gof.py
class ExSubject(EasyWindow, Subject):
def _init(self):
self.observers = []

def addObserver(self, observer):
self.observers.append(observer)

メソッド addObserver では、Subject に依存する observer を、インスタンス属性 self.observers に登録 append します。後で、Subject の状態が変化したときには、self.observers が保持するすべての要素 observer に対して、その旨を通知する必要があります。

2)事後の更新/通知:update

次に、Subject の状態が変化したことを、それに依存する Observer に通知します。

# Observer_gof.py
class ExSubject(EasyWindow, Subject):
def _init(self):
self._listBox.SelectionChanged += self.selectionChanged

def selectionChanged(self, sender, e):
s = sender.SelectedItem.Content
for e in self.observers:
e.update(s)

リスト項目を選択すると、イベント SelectionChanged が発生します。これに呼応してイベントハンドラー selectionChanged では、self.observers が保持する各要素 e に対して、Subject の状態が変化したことを通知 update します。
ExObserver の傘下にあるクラスでは、通知された message を頼りに、それぞれの状態を更新します。

# -------------------------------------------------- before ---
class ButtonObserver(ExObserver):
def update(self, message):
self._textBox.Text = message
通知された message をそのまま、テキスト領域 .Text に設定します。

class SliderObserver(ExObserver):
def update(self, message):
brush = getattr(Brushes, message)
self._colorBox.Background = brush
e = brush.Color
self.R.Value = e.R
self.G.Value = e.G
self.B.Value = e.B

通知された message から色情報 brush を獲得して、キャンバスの背景色 .Background を設定します。また、色成分(赤/緑/青)ごとに、スライダーの値 .Value を再設定します。


Previous|1/3|Next

適用事例: Observer パターン

値の更新/通知で、すぐに思い浮かぶのは古典的な〈GoF〉Observer パターンです。そこで、このパターンに、データバインディングを導入した事例を紹介します。

《付記》この事例は、説明のために用意したもので「未完成」です。

まず、パターンの復習から始めます。古典的な Observer パターンを踏襲したのが、Observer.py です。これを実行すると、次のようなウィンドウが現れます。


(上)リスト項目を選択すると(左)テキストボックスには色名が表示され(右)スライダーは色成分ごとに調整されて、キャンバスにその色が表示されます。この事例では、Subject の状態が変化すると、Observer も自分の状態を更新します。そのためには、1)事前の登録、2)事後の更新/通知の手順を踏む必要があります。