適用事例:〈GoForward〉Observer パターン

古典的な Observer パターンは、単純な作業の繰り返しです。しかし、その数が膨大になると、それなりに労力を割かれます。そこに、データバインディングを導入すると、その労力を軽減できるだけでなく、仕様変更にも柔軟に対処できます。また、分離コードを導入することで、プログラミング言語に依存しない恩恵に浴します。

何が問題か

Subject の状態に依存して変化する Observer では、それぞれの状態を更新する必要があります。そのとき「テキストボックスの Text= の値は…に、キャンバスの Background= の値は…に、スライダーの Value= の値は…に」といった具合に、手作業でコードを記述する(ハードコーディング)作業を余儀なくされます。そこに、データバインディングを導入すると、その手間を省けるだけでなく、分離コードを記述する「プログラミング言語に依存しない」という恩恵があります。

《Note》何が問題か:単純な軽作業でも、その数が膨大になると重労働です。また、作業が単調なだけにミスを誘発しやすく、得てしてバグの発見も困難になりがちです。さらに醜悪なのは、些細な仕様変更にも、大量のコードの変更を余儀なくされることです。というのも、特定の実現方法(コンポーネント)に依存するコードが、散在する傾向にあるからです。この醜態を象徴するのが「西暦二千年〔Y2K〕問題」でした。Y2K は、その後も様々にその姿を変えて、今日もなお健在です。◆ 既存のコンポーネントを利用しているだけなら、仕様変更が頻発する心配はないかもしれません。しかし、実際のアプリケーション開発の現場ではどうでしょう。仕様変更があると、開発の途上にあるコンポーネントに依存するコードを、すべて書き換える必要に迫られます。たとえ一行でも変更したなら(残りの膨大なコードは変更していないのに)再コンパイルを余儀なくされます。これでは、アジャイル開発も失速します。◆ 分離コードは、このような問題解決の有効な処方箋のひとつになります。♪ひよ子 □

Observer パターンに代えて

古典的な Observer パターンに、データバインディングを導入したのが、サンプルファイル Observer.py です。ExObserver の傘下にあるクラスで、個別にメソッド update を実現する代わりに、ここで共通のメソッド update を実現します。


# -------------------------------------------------- after ---
class ExObserver(EasyWindow, Observer):
def update(self, message):
self.DataContext = ColorItem(message)
データバインディングを導入する前と比較すると、この分離コードは単純です。ただ、データコンテキスト
self.DataContext に、依存する対象を設定するだけです。
class ButtonObserver(ExObserver): pass
class SliderObserver(ExObserver): pass

さらに、その傘下では「何もする必要がない」ので、単に pass とするだけです。後は、XAML ファイルが(プログラマーに代わって)単純/煩雑な作業を遂行します。
仕様変更に伴って、他のコントロールを利用することになっても、分離コードには影響しません。プログラマーは、データコンテキストに依存しない、アプリケーションの本質的な部分の開発に専念できます。
《Tips》データバインディングを導入すると、コードが単純になるだけでなく(情報隠蔽の原則に従って)その保守も容易になります。プログラマーは、些末な作業から解放されて、本質的な作業に専念できます。「楽をするための努力なら惜しみません」とする、タマゴ倶楽部のモットーにも合致します。(^_^)□
《Note》この適用事例は未完です。古典的な GoF を卒業して、その先へ踏み出す go forward には、Python の洗練された機能が役立ちます。さらに、ソースの状態変化を、ターゲットの属性に自動的に反映させるためには、INotifyPropertyChanged/PropertyChanged などの理解が前提となります。すると、新たな問題解決の展望が開けてきます。これらの話題については、他の記事で紹介します。□


Previous|2/3|Next