ãWindowsãã¯ããã¨ããGUIã®æ®åã«ãããã®ããObserverãã¿ã¼ã³ã¯æ°ãããã¶ã¤ã³ãã¿ã¼ã³ã®ä¸ã§ãé©ç¨é »åº¦ã®é«ããã®ã®ä¸ã¤ã§ããGUIã¢ããªã±ã¼ã·ã§ã³ã§ã¯ãã¼å ¥åããã¿ã³ã¯ãªãã¯ã¨ãã£ãã¤ãã³ããåçããã¨ãã®å¦çï¼ã¤ãã³ããã³ãã©ï¼ãå®ç¾©ããã¤ãã³ãã¨ã¤ãã³ããã³ãã©ã¨ã®å¯¾å¿ä»ããè¡ã£ã¦ããã¾ãããããããã¨ã§ã¤ãã³ãã«å¿ããå¦çãããªãã¡ãã¤ãã³ãã«åå¿ããããã¨ãã§ãã¾ããã¤ãã³ãã¨ã¤ãã³ããã³ãã©ã¨ã®å¯¾å¿ä»ãã«ç¨ãããã¦ããã®ãObserverãã¿ã¼ã³ã¨ããããã
step-1: Subjectã¨Observer
ãObserverãã¿ã¼ã³ã§ã¯2ã¤ã®ã¯ã©ã¹ãSubjectã¨Observerãé¢ä¸ãã¾ããSubjectã¯ã¤ãã³ãã®çºè¡å ãObserverãã¤ãã³ãã«åå¿ãããã³ãã©ã®åºåºã¯ã©ã¹ã¨ãªãã¾ããObserverã«ã¯ããããããã¤ãã³ãã«åå¿ãã¦å¼ã³åºãããã¡ã½ããï¼ãã³ãã©ï¼ã宣è¨ãã¦ããã¾ããã¾ãSubjectå ã«ã¯Observerã¸ã®åç §ï¼ãã¤ã³ã¿ï¼ãä¿æããã³ã³ãããå å ããã¦ããã¾ããSubjectã¯å å ããã³ã³ããã®åè¦ç´ ï¼Observerã®åç §ï¼ã«å¯¾ãããã³ãã©ãå¼ã³åºããã¨ã§ã¤ãã³ãé§åãå®ç¾ã§ãã¾ããããã¾ã§ã¯æ¥µãã¦åç´ãªããããã§ãããã£ããå®è£ ãã¦ã¿ã¾ãããã
/* [step-1] * ã·ã³ãã«ãªObserverãã¿ã¼ã³å®è£ */ #include <vector> #include <algorithm> 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ã®ãã³ãã©ãå¼ã³åºã void notify() { std::for_each(obs_.begin(), obs_.end(), [this](Observer* o) { o->update(this);}); } }; /* * ãããã */ #include <iostream> // 室温 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; } }; int main() { RoomTemp room(20); TempDisp disp; room.add_observer(&disp); room.increment(); room.increment(); room.increment(); room.decrement(); room.decrement(); room.decrement(); }
ããªããªãåãã¦ããã¾ããããä¸ã¤ä¸ä¾¿ãªç¹ãããã¾ããä¾ãã°ãããªã³ã¼ãã§ã¯ã©ãã§ãããã
int main() { RoomTemp room(20); { TempDisp disp; room.add_observer(&disp); room.increment(); room.increment(); room.increment(); } // [*] room.decrement(); room.decrement(); room.decrement(); }
ãï¼»ï¼ï¼½ã«éããæç¹ã§Observerã§ããdispã¯å¯¿å½ãã¾ã£ã¨ããããã®ä¸ããæ¶ãã¦ãªããªãã¾ããã¨ãããSubjectã§ããroomã¯dispã®ãã¤ã³ã¿ãä¿æããã¾ã¾ã«ãªã£ã¦ãã¾ããå¾ã£ã¦ãã®å¾ã® room.decrement() ã«ãã£ã¦ãã®ä¸ã«ããªãdispã®ã¡ã½ããupdate()ãå¼ã°ãããã¨ã«ãªãããã®çµæã¯æªå®ç¾©ã§ãã
ãObserverããã®å½¹å²ãçµããã¨ãã¯ãããã«å ç«ã£ã¦å¿ ãå¾å§æ«ï¼delete_observerï¼ããªããã°ãªããªãã®ã§ãããstd::shared_ptrã使ã£ã¦å¾å§æ«ã®ãããªãObserverã®å®è£ ã試ã¿ã¾ãããã