デザインパターンとは、システム設計におけるクラスやインターフェースの関係に名前をつけたものです。 GoFの23のパターンが有名です。デザインパターンというのは、どんなパターンなのか、パターンの目的は何かということを覚えることが非常に重要なのですが、これを実際に適用しようとした場合に、いつ適用していいかが見えてこないとお話になりません。
そこで、自分の勉強も兼ねつつ、パターンの実践時における使用場所や、パターンを適用するきっかけを見つけられるようにメモしておきます。
14番目のパターンは観察対象の状態が変化を通知しそれに沿って処理を行うというObserverパターンのメモです。
Observerパターン
Observerパターンは、観察対象(Subject)のオブジェクトの状態が変化したときに、共通の方法で観察者(Observer)に通知することを意図したものです。
このパターンは主に、GUIシステムで使われます。GUIシステムでは、データを持つBeanオブジェクトと、それを表示するビューオブジェクトがきれいに分かれているのが一般的です。このとき、オブジェクト指向の原則の一つである「オープン・クローズドの原則(OCP)」を意識して設計を進めると、次第にObserverパターンが有効に働いてくるのです。
参考
観察対象であるSubjectは、自分がどのObserverに観察されているかは知りません。ただ、観察されているという事実と、自分の状態に変化があった場合に、notifyメソッドを呼び出して、すべてのObserverのupdateを呼び出してやるだけです。
Observerパターンには、2つの種類があります。updateを呼び出す時の振る舞いが2つあるのです。一つは、updateの引数に変更された状態を渡すことで、Observerに通知する「push」型。もう一つは、updateを呼び出されたタイミングでObserverがSubjectに状態を問い合わせる「pull」型です。
push型の特徴
push型は、ObserverがSubjectのどの状態が変更されたのかを直接知ることができるのが特徴です。updateの引数で渡されてきたものが、変更された状態だからです。短所は、updateメソッドに引数をとる形でインターフェースを定義しなければならないので、一般化に向かない点です。
pull型の特徴
pull型は、一般化した形でupdateメソッドを定義できます。しかし、Subjectのどの状態が変更されたのかをSubjectに問い合わせなければなりません。Subjectに状態が非常にたくさんある場合は、なんらかの方法を使わなければ、複雑になってしまいます。
「push型」と「pull型」のどちらを使うかは、単純にSubjectの状態の複雑さで決めればいいと思います。Subjectの状態が単純でならばpush型。Subjectの状態が複雑で、多くのフィールドを持つような場合はpull型にするといいと思います。
参考
パターンの適用タイミング
Observerパターンは、次のような場合に使えます。状態を持つオブジェクトが、状態変化を通知したいが、通知後の処理については知りたくない場合。(上位層が下位層に依存したくない場合)
実装サンプルと参考文献
日立ソフト(Observerパターン) 日立ソフト
Skeleton of GOF’s Design Pattern(JavaとC++のサンプルがあります) Observerの骸骨
デザインパターンのお勧め書籍
- 独習シリーズのデザインパターン編。デザインパターンを一人でも学べます。
- Sun Microsystemのお墨付き。GoF以外のパターンも学べます。
- UMLを使って、オブジェクト指向のいいとこ取りができます。
- デザインパターンだけではなく、ソフトウェア設計の原則やプラクティスまで学びたい人におすすめ