Python.use(better) # Let's GoForward《8》Observer(8)パターン夜明け前
|記事一覧|《こちらに移動中です》2007年6月20日 (水)
Python.use(better) # Let’s GoForward
《8》Observer(8)パターン夜明け前《Jython2.5.0》
■ 概要
GoF の事例を鵜呑みにすると、迂遠なアプローチを余儀なくされるばかりか、Python の洗練された特徴を活かせずに損をします。GoF を模写しても始まりません。GoF が模写したその起源を探ることで、パターンの本質に迫れます。Let's Go Forward (^.^)
《8》Observer(8)パターン夜明け前★★
(承前)共通するインターフェースとして Observer を実現します。
class CanvasView(JPanel, Observer): def __init__(self, subject): self.subject = subject self.subject.addObserver(self) def update_(self): self.repaint() def paint(self, g): color = self.subject.color() if color: x, y, w, h = 0, 0, self.width, self.height g.color = color g.fillOval(x, y, w-1, h-1)
変更したクラス CanvasView は、インターフェース Observer を実現します。メソッド update_ は、インターフェース Observer で規定されたもので、最新情報を使って、自分が表示すべき内容を更新します。ここでは、Swing/Java が提供するフレームワークに従って、repaint に呼応して呼び出される paint を実現します。
class TextView(JTextArea, Observer): def __init__(self, subject): JTextArea.__init__(self, lineWrap=True, wrapStyleWord=True) self.subject = subject self.subject.addObserver(self) def update_(self): color = self.subject.color() self.text = "" self.append("%s\n"%color)
変更したクラス TextView は、インターフェース Observer を実現します。メソッド update_ は、インターフェース Observer で規定されたもので、最新情報を使って、自分が表示すべき内容を更新します。
このようにして、Observer を規定する前の repaint/redisplay の違いを、共通の update_ に集約したことで、ポリモフィズムによる情報隠蔽が実現できました。
再利用したコンポーネントに依存しない、共通のインターフェース Observer の規定に従うことで、相互の独立性を維持できます。あるサービスを利用したいときには、Observer で規定されたプロトコルに準拠するなら、何をしてもかまいません。あるサービスを提供したいときには、Observer で規定されたプロトコルに準拠するなら、どのように実現してもかまいません。
ここでは、異なるコンポーネント JPanel および JTextArea を利用していても、指定された色情報をどのように表示するかに関係なく、共通のメソッド update_ を利用できます。今後、新たなコンポーネントを導入したいときにも、Observer で規定されたプロトコルに準拠するなら、既存のリソースを改変する必要はありません。
==================================
伊藤うさぎ 著 ◆ 監修:小泉ひよ子とタマゴ倶楽部