Observer

パターンの目的

あるオブジェクトが状態を変えた時に、それに依存するすべてのオブジェクトに自動的にそのことが知らされ、また、それらが更新されるように、オブジェクト間に一対多の依存関係を定義する。

GoF パターンのクラス図

structure-08-05:observer

MixJuice 版 Observer (改善)

解決される GoF パターンの問題点

導入可能性の問題点
既存のクラスを Subject や Observer として利用することができない。
拡張性の問題点

p.318:

  1. observer ごとに更新プロトコルが異なるようなことは避ける(push モデルと pull モデル)。

Observer パターンの実装では、しばしば subject に、変化についての付加的な情報をブロードキャストさせるようにする。 subject はこの情報を Update オペレーションの引数として渡す。やりとりの方法により、情報量にはかなりの差が生じるだろう。

ここで observer の種類により、必要な情報は異なるが、 Java では update オペレーションの引数が後から変更できないため、適切に情報を渡せない。

対策

Observer の登録機構を別モジュールで定義する。これにより、既存のクラスを Subject/Observer として利用できるようになる。

また、拡張性の問題に対しては、必要に応じて、新しい update オペレーションを定義する。 MixJuice では既存のクラスを後から変更できるのでこれが可能である。

結果

構造

structure-08-09:observer

module original {
  define class Subject {
    define void sideEffectOperation() {...}
  }
}

module extension extends original {
  define abstract class Observer {
    define abstract void update();
  }

  class Subject {
    define void attach(Observer o) {...}
    define void detach(Observer o) {...}
    define void changed() {...}

    void sideEffectOperation() {
      original();
      changed();
    }
  }
}

サンプルコード

関連するパターン


MixJuice によるデザインパターン改善カタログ


田中 哲 <akr@m17n.org>, 一杉 裕志 <y-ichisugi@aist.go.jp>