Python.use(better)《16》Observer(16)パターンの午後:GoGoForward
|記事一覧|
Python.use(better) # Let’s GoForward《Jython2.5.0》
Observer《余録》パターンの午後:GoGoForward
■ 概要
GoF が何を伝えなかったのか、それを伝える準備が整いました。
GoF の事例を鵜呑みにすると、迂遠なアプローチを余儀なくされるばかりか、Python の洗練された特徴を活かせずに損をします。GoF を模写しても始まりません。GoF が模写したその起源を探ることで、パターンの本質に迫れます。Let's Go Forward (^.^)
Observer(16)パターンの午後:GoGoForward
《Note》他人のものは自分のもの:1対Nの依存関係を扱うのには、Observer パターンが有効です。前述した事例では、1対2の依存関係を扱いましたが、さらに1対Nの依存関係へと発展します。部分全体関係に着目すると、自身と他者との間だけでなく、自身(全体)を構成する要素(部分)の中にも、依存関係が存在するのが分かります。それは、環境の影響だけでなく、自身の体調にも影響される様に似ています。
選択した項目が変化すると、他の部品を再描画する必要があります。このとき、状態変化に呼応するのが自身か他者かを意識せずに、1対Nの依存関係に着目した「統一的なモデル」を構築できます。
class ColorPanelView(JPanel, Observer): def __init__(self, subject, preferredSize): JPanel.__init__(self, preferredSize=preferredSize) subject.attach_(self) def update_(self, value): self.background = value
〔変更〕クラス ColorPanelView では、Observer の規定に従って、依存関係を実現します。
- 〔変更〕メソッド __init__ は、subject の状態変化に呼応する対象の中に、自分を登録 attach_(self) します。
- 〔追加〕メソッド update_ は、subject の状態が変化したときに、背景色 value を設定します。
class ColorPanel(JPanel, Subject): def __init__(self, listData): Subject.__init__(self) self.model = ColorModel() self.listView = ColorListView( data=listData, changed=self.notify_) self.panelView = ColorPanelView( self, preferredSize=(100, 100)) self.add(JScrollPane(self.listView), BorderLayout.CENTER) self.add(self.panelView, BorderLayout.EAST) def notify_(self, e): value = e.source.value() value = self.model.color(value) self.panelView.background = value for e in self.observers: e.update_(value) def color(self): ...
〔変更〕クラス ColorPanel では、ColorPanelView の状態変化に呼応する対象の中に、自分 self を登録 Subject.__init__(self) します。
- 〔変更〕メソッド notify_ では、他の observers と同様に、ColorPanelView にも状態変化を通知 update_ します。