GoFのデザインパターン(Design Pattern)のオブザーバー(Observer)のRubyコードを使った紹介記事です。
次の条件を満たす場合にオブザーバーパターンを使います。
* オブジェクトの状態が変化する可能性がある * 変化したことを他のオブジェクトに通知する必要がある
例としては、Aで起きたイベントをB, Cが知る必要が有る場合などです。
オブザーバーとは?
あるオブジェクトの状態が変化した際に、そのオブジェクト自身が「観察者」に「通知」する仕組みです。オブザーバは以下の3つのオブジェクトによって構成されます。
サブジェクト(subject):変化する側のオブジェクト オブザーバ(Observer):状態の変化を関連するオブジェクトに通知するインタフェース 具象オブザーバ(ConcreteObserver):状態の変化に関連して具体的な処理を行う
オブザーバのメリット
オブジェクト間の依存度を下げることができる 通知先の管理をオブザーバが行うことで、サブジェクトは通知側を意識しなくていい
サンプルソース
次のようなモデルを通してObserverデザインパターンを説明します。
Employee(サブジェクト):従業員を表す Observable(オブザーバ):従業員のニュースを監視する仕組み(observer/Observable) Payroll(具体オブザーバ1):給与の小切手の発行を行う TaxMan(具体オブザーバ2):税金の請求書の発行を行う
まずは従業員を表すEmployeeクラスについてです。このEmployeeクラスは、name, title, salaryといったデータと、salaryの変更を受け付けるメソッドを持っています。
さらに、Employeeクラスにobservableをincludeします。observableはオブザーバーとしての機能を持ったrubyの標準モジュールです。
observableで用いるメソッドは次のとおりです。
add_observerメソッドで通知する先のオブジェクトを追加changedメソッドとnotify_observersメソッドでオブジェクトに通知
こちらが、Employeeクラスの実装です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
次に給与の小切手の発行を行うPayrollクラスと、税金の請求書の発行を行うTaxManクラスを作成します。これらは具体オブザーバ(ConcreteObserver)にあたります。
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
コーディングは以上です。では結果を確認します。
1 2 3 4 5 6 7 | |
johnのsalary(給与)を変更するとObservableによってPayrollクラスと、TaxManクラスのupdateメソッドが連動して動いていることがわかります。
このサンプルソースはGitHubにも置いています。
ストラテジーとの違い
オブザーバ:発生しているオブジェクトに対してイベントを通知している ストラテジー:何らかの処理を行うためにオブジェクトを取得している
Special Thanks
Amazon.co.jp: Rubyによるデザインパターン: Russ Olsen, ラス・オルセン, 小林 健一, 菅野 裕, 吉野 雅人, 山岸 夢人, 小島 努: 本
Special Thanks
@y_shindohさんにコードのタイポを指摘して頂きました。 ご丁寧に間違っていた部分のdiffを作って頂けたお陰ですぐに修正出来ました。有難うございます^^
変更来歴
12/12/10 09:00 GitHubへのサンプルソースの設置。導入文の修正
12/12/11 00:00 書籍へのリンクをAmazon アフィリエイトに変更
12/12/15 23:30 ソースコードに説明を追加
13/06/20 17:40 Ruby2.0.0対応、読みづらい部分を修正
15/01/16 20:50 タイポの修正