Python.use(better)《7》Observer(7)パターン夜明け前

記事一覧《こちらに移動中です》2007年6月19日 (火)

Python.use(better) # Let’s GoForward
Observer(7)パターン夜明け前《Jython2.5.0》

《著》森こねこ・後藤いるか・伊藤うさぎ・小粒ちゃん+∞《監修》小泉ひよ子とタマゴ倶楽部
第1版♪1995/01/29

■ 概要

GoF の事例を鵜呑みにすると、迂遠なアプローチを余儀なくされるばかりか、Python の洗練された特徴を活かせずに損をします。GoF を模写しても始まりません。GoF が模写したその起源を探ることで、パターンの本質に迫れます。Let's Go Forward (^.^)

《7》Observer(7)パターン夜明け前★★

(承前)共通するインターフェースとして Observer を規定します。

class ColorPanel(JPanel):
    def valueChanged(self, e):
        value = e.source.selectedValue
        self.panelView.background = self.model.color(value)
        if self.observer:
            self.observer.update_()

 変更したクラス ColorPanel は、新たに規定したプロトコルに従います。そこで、observer を更新には、新たなメソッド update_ を利用します。インターフェースを規定する前の repaint/redisplay の違いを、もう気にする必要はありません。

class Observer:
    def update_(self):
        raise NotImplementedError, \
            "%s::def update_(self)"%self.__class__.__name__

 クラス Observer は、共通するインターフェースを規定します。メソッド update_ は、その最新情報に従って、各コンポーネントの内容を更新します。依存するクラスで、このメソッドを定義していないと、次のようなエラーメッセージが出力されます。

NotImplementedError: CanvasView::def update_(self)

 クラス CanvasView/TextView では、多重継承を使って、それぞれ固有の親クラス JPanel/JTextArea とは別に、共通のインターフェースを規定したクラス Observer の特性を実現します。Java では、単一継承を使って同じ概念を実現する必要があるので、Observer は interface を使って実現します。Jython では、多重継承が可能ですが、Java で実現した親クラスの数は1つに限定されます。これが意味するのは、Jython では「Java で規定された制約を犯してはならない」ということです。
開発プロセスを支援するメッセージ:NotImplementedError を使っても、開発された`プロダクト`には影響しません。しかし、必要なメソッドを実現していないと、プログラマーに注意を促します。これは、Smalltalk における、subclassResponsibility に相当するもので、開発する`プロセス`を支援するメッセージのひとつとして、抽象クラスには必須です。つまり、抽象クラスは、Java/C# のように、文法が強制的に規定する「義務」ではなく、Python では、プログラマーが自発的に規定する「権利」なのです。《ひよ子》
【注意】ここで、update ではなく、update_ としたのは、先祖クラスが提供する update と重複しないようにするためです。

Last updated♪2009/07/29