Observerとは、英語で観察者を意味します。
Observer パターンとは、状態の変化を観察することを目的としたものですが、どちらかというと「観察」よりも「通知」に重点の置かれたものになっています。
あるインスタンスの状態が変化した際に、そのインスタンス自身が、「観察者」に状態の変化を「通知」する仕組みです。
<Observerパターンの定義 : クラス図>
[ObserverSample.h]
#include <vector> #include <algorithm> #include <iostream> class Observer { friend class Subject; public: virtual ~Observer() {} protected: virtual void update(Subject*) = 0; }; class Subject { private: std::vector<Observer*> obs_; public: // Observerを登録 void add_observer(Observer* o) { if (std::find(obs_.begin(), obs_.end(), o) == obs_.end()) { obs_.push_back(o); } } // Observerの登録抹消 void delete_observer(Observer* o) { auto iter = std::find(obs_.begin(), obs_.end(), o); if (iter != obs_.end()) { obs_.erase(iter); } } protected: // 登録されたObserverのハンドラを呼び出す // std::for_each ⇒ 範囲の全ての要素に、指定された関数を適用する // oの全ての要素にラムダ式を適用する // 【thisのキャプチャ】 // メンバ関数内では、thisをキャプチャすることでラムダ式内でメンバ変数、メンバ関数(update)を使用することができます。 // 下記のラムダ式では、thisをキャプチャして、vector[obs_]の各要素のObserverオブジェクトのupdateメソッドを使用しています。 void notify() { std::for_each(obs_.begin(), obs_.end(), [this](Observer* o) { o->update(this); }); } }; // 具象サブジェクト // 室温 class RoomTemp : public Subject { private: int value_; // public: RoomTemp(int initial) : value_(initial) {} void increment() // 室温を1度上げる { ++value_; notify(); } void decrement() // 室温を1度下げる { --value_; notify(); } int get_temp() const // 現在の室温 { return value_; } }; // 具象オブサーバクラス // 温度表示パネル : 室温の変化に応じて室温を表示する class TempDisp : public Observer { public: ~TempDisp() { std::cout << "お疲れ様でしたー" << std::endl; } protected: virtual void update(Subject* from) { int temp = static_cast<RoomTemp*>(from)->get_temp(); std::cout << "現在の温度: " << temp << "℃" << std::endl; } };
[main.cpp]
#include "ObserverSample.h" int main() { RoomTemp room1(20); RoomTemp room2(30); TempDisp disp1; TempDisp disp2; room1.add_observer(&disp1); room2.add_observer(&disp2); room1.increment(); room1.increment(); room1.increment(); room2.decrement(); room2.decrement(); room2.decrement(); }
実行結果
以下のサイトを参考にさせていただきました。
参考リンク
以下のリンクがわかりやすいです。 * 地下アイドルとアイドルオタクを疎結合にしてみたら、夢も希望もなくなった〜デザインパターンのObserverを考える〜 - Qiita