用C++实现观察者模式的几种变体

打印 上一主题 下一主题

主题 1043|帖子 1043|积分 3129

观察者模式的标准定义

定义一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当这个主题对象的状态发生改变时,会关照所有观察者对象,使它们可以或许主动更新自己的状态。
观察者模式的标准结构图


观察者模式的标准实现

Subject(抽象主题)

Subject.h
  1. #pragma once
  2. #include <list>
  3. #include <string>
  4. class Observer;
  5. class Subject
  6. {
  7. public:
  8.         virtual ~Subject();
  9.         virtual void addObserver(Observer* obsv);
  10.         virtual void removeOvserver(Observer* obsv);
  11.         virtual void notify();
  12. private:
  13.         std::list<Observer *> mObserverList;
  14. };
复制代码
Subject.cpp
  1. #include "Subject.h"
  2. #include "Observer.h"
  3. Subject::~Subject()
  4. {
  5.         if (!mObserverList.empty())
  6.         {
  7.                 mObserverList.clear();
  8.         }
  9. }
  10. void Subject::addObserver(Observer* obsv)
  11. {
  12.         if (nullptr == obsv)
  13.                 return;
  14.         bool bExist = false;
  15.         std::list<Observer*>::const_iterator iter = mObserverList.begin();
  16.         for (; iter != mObserverList.end(); ++iter)
  17.         {
  18.                 Observer* const curObsv = iter.operator*();
  19.                 //*iter == obsv;
  20.                 if (curObsv == obsv)
  21.                 {
  22.                         bExist = true;
  23.                         break;
  24.                 }
  25.         }
  26.         if (bExist)
  27.                 return;
  28.         mObserverList.push_back(obsv);
  29. }
  30. void Subject::removeOvserver(Observer* obsv)
  31. {
  32.         if (mObserverList.empty() || (nullptr == obsv))
  33.                 return;
  34.         bool bExist = false;
  35.         std::list<Observer*>::const_iterator iter = mObserverList.begin();
  36.         for (; iter != mObserverList.end(); ++iter)
  37.         {
  38.                 Observer* const curObsv = *iter;
  39.                 if (curObsv == obsv)
  40.                 {
  41.                         bExist = true;
  42.                         break;
  43.                 }
  44.         }
  45.         if (bExist)
  46.                 mObserverList.remove(obsv);
  47. }
  48. void Subject::notify()
  49. {
  50.         std::list<Observer*>::const_iterator iter;
  51.         for (iter = mObserverList.begin(); iter != mObserverList.end(); ++iter)
  52.         {
  53.                 Observer* const curObsv = *iter;
  54.                 curObsv->update();
  55.         }
  56. }
复制代码
这里先说两个概念:原语函数钩子函数
原语函数,即纯虚函数,意思就是必须在子类中重定义的函数;
钩子函数,即虚函数,意思是可以在子类中重定义的函数。
ConcreteSubject(具体主题)

ConcreteSubject.h
  1. #pragma once
  2. #include "Subject.h"
  3. class ConcreteSubjectA :
  4.     public Subject
  5. {
  6. public:
  7.     void setState(bool b);
  8.     bool getState() const;
  9.     void changedState();
  10. private:
  11.     bool mSendToA = false;
  12.     bool mSendToB = false;
  13. };
复制代码
ConcreteSubject.cpp
  1. #include "ConcreteSubjectA.h"
  2. #include <iostream>
  3. void ConcreteSubjectA::setState(bool b)
  4. {
  5.         mSendToA = mSendToB = b;
  6.         changedState();
  7. }
  8. bool ConcreteSubjectA::getState() const
  9. {
  10.         return (mSendToA && mSendToB);
  11. }
  12. void ConcreteSubjectA::changedState()
  13. {
  14.         std::cout << "刘亦菲来啦~" << std::endl;
  15.         if (getState())
  16.         {
  17.                 notify();
  18.         }
  19. }
复制代码
Observer(抽象观察者)

Observer.h
  1. #pragma once
  2. class string;
  3. class Observer
  4. {
  5. public:
  6.         Observer();
  7.         virtual ~Observer();
  8.         virtual void update() = 0;
  9. };
复制代码
Observer.cpp
  1. #include "Observer.h"
  2. Observer::Observer()
  3. {
  4. }
  5. Observer::~Observer()
  6. {
  7. }
复制代码
ConcreteObserverA(具体观察者A)

ConcreteObserverA.h
  1. #pragma once
  2. #include "Observer.h"
  3. class ConcreteObserverA :
  4.     public Observer
  5. {
  6. public:
  7.     ConcreteObserverA();
  8.     ~ConcreteObserverA();
  9.     virtual void update() override;
  10. };
复制代码
ConcreteObserver.cpp
  1. #include "ConcreteObserverA.h"
  2. #include <iostream>
  3. ConcreteObserverA::ConcreteObserverA()
  4. {
  5. }
  6. ConcreteObserverA::~ConcreteObserverA()
  7. {
  8. }
  9. void ConcreteObserverA::update()
  10. {
  11.         std::cout << "我要上报给领导!" << std::endl;
  12. }
复制代码
ConcreteObserverB(具体观察者B)

ConcreteObserverB.h
  1. #pragma once
  2. #include "Observer.h"
  3. class ConcreteSubjectA;
  4. class ConcreteObserverB :
  5.     public Observer
  6. {
  7. public:
  8.     ConcreteObserverB();
  9.     virtual ~ConcreteObserverB();
  10.     virtual void update() override;
  11. };
复制代码
ConcreteObserverB.cpp
  1. #include "ConcreteObserverB.h"
  2. #include "ConcreteSubjectA.h"
  3. #include <iostream>
  4. ConcreteObserverB::ConcreteObserverB()
  5. {
  6. }
  7. ConcreteObserverB::~ConcreteObserverB()
  8. {
  9. }
  10. void ConcreteObserverB::update()
  11. {
  12.         std::cout << "我要通知其他人!" << std::endl;
  13. }
复制代码
主程序简单调用

  1. #include "ConcreteObserverA.h"
  2. #include "ConcreteSubjectA.h"
  3. #include "ConcreteObserverB.h"
  4. #include <iostream>
  5. int main()
  6. {
  7.     // Standard version
  8.     ConcreteObserverA* obsvA = new ConcreteObserverA();
  9.     ConcreteObserverB* obsvB = new ConcreteObserverB();
  10.     ConcreteSubjectA* subA = new ConcreteSubjectA();
  11.     subA->addObserver(obsvA);
  12.     subA->addObserver(obsvB);
  13.     subA->setState(true);
  14.     subA->removeOvserver(obsvB);
  15.     subA->removeOvserver(obsvA);
  16.     return EXIT_SUCCESS;
  17. }
复制代码
实在到这里,可以结束了;但是,好像又远远不敷。哪里不敷呢?
你难道不以为这两个观察者A、B有点太轻信于主题A了吗?不管谁给它们发消息,它们都相信 ,如许容易上当上当呀——说是刘亦菲来了,实在是刘姥姥来啦~。
观察者A、B也很委屈,腹诽道:我也不知道是谁给我的消息,我只知道,有消息,我就得做出反应;哪里还管得了你的、他的。
这还不简单…
观察者变身一

Observer.h
  1. #pragma once
  2. #include "Subject.h"
  3. class Observer_SecondVer // 响应固定主题
  4. {
  5. public:
  6.         Observer_SecondVer();
  7.         Observer_SecondVer(Subject* subject);
  8.         virtual ~Observer_SecondVer();
  9.         virtual void update(Subject* subject = nullptr) = 0;
  10. protected:
  11.         Subject* mSubject = nullptr;
  12. };
复制代码
ConcreteObserverA.h
  1. #pragma once
  2. #include "Observer.h"
  3. class ConcreteObserverA_SecondVer : public Observer_SecondVer
  4. {
  5. public:
  6.     ConcreteObserverA_SecondVer();
  7.     ConcreteObserverA_SecondVer(Subject* subject);
  8.     ~ConcreteObserverA_SecondVer();
  9.     virtual void update(Subject* subject = nullptr) override;
  10.     void doSomething();
  11. };
复制代码
ConcreteObserverA.cpp
  1. #include "ConcreteObserverA.h"
  2. #include <iostream>
  3. ConcreteObserverA_SecondVer::ConcreteObserverA_SecondVer()
  4. {
  5. }
  6. ConcreteObserverA_SecondVer::ConcreteObserverA_SecondVer(Subject* subject) : Observer_SecondVer(subject)
  7. {
  8. }
  9. ConcreteObserverA_SecondVer::~ConcreteObserverA_SecondVer()
  10. {
  11. }
  12. void ConcreteObserverA_SecondVer::update(Subject* subject)
  13. {
  14.         if (subject && subject == mSubject)
  15.         {
  16.                 doSomething();
  17.         }
  18. }
  19. void ConcreteObserverA_SecondVer::doSomething()
  20. {
  21.         std::cout << "通知老板!" << std::endl;
  22. }
复制代码
ConcreteObserverB.h
  1. #pragma once
  2. #include "Observer.h"
  3. class ConcreteSubjectA;
  4. class ConcreteObserverB_SecondVer : public Observer_SecondVer
  5. {
  6. public:
  7.     ConcreteObserverB_SecondVer();
  8.     ConcreteObserverB_SecondVer(ConcreteSubjectA* subject);
  9.     ~ConcreteObserverB_SecondVer();
  10.     virtual void update(Subject* subject = nullptr) override;
  11.     void doSomething();
  12. };
复制代码
ConcreteObserverB.cpp
  1. #include "ConcreteObserverB.h"
  2. #include "ConcreteSubjectA.h"
  3. #include <iostream>
  4. ConcreteObserverB_SecondVer::ConcreteObserverB_SecondVer()
  5. {
  6. }
  7. ConcreteObserverB_SecondVer::ConcreteObserverB_SecondVer(ConcreteSubjectA* subject) : Observer_SecondVer(subject)
  8. {
  9. }
  10. ConcreteObserverB_SecondVer::~ConcreteObserverB_SecondVer()
  11. {
  12. }
  13. void ConcreteObserverB_SecondVer::update(Subject* subject)
  14. {
  15.         if (subject && subject == mSubject)
  16.         {
  17.                 doSomething();
  18.         }
  19. }
  20. void ConcreteObserverB_SecondVer::doSomething()
  21. {
  22.         std::cout << "通知其他人!" << std::endl;
  23. }
复制代码
怎么样?以后,只要观察者A、B认定了主题A的消息,都进行相应,是不是就没那么容易上当上当了。
突然,观察者A又有点其他的想法,弱弱地问道:“那个~我不想只看刘亦菲,只要是美女,能不能都给我发消息呀?”
啊~ 你这~
于是乎…
主题变身一/二 + 观察者变身二

Subject.h
  1. #pragma once
  2. #include <list>
  3. #include <string>
  4. class Observer;
  5. class Observer_SecondVer;
  6. class Observer_ThirdVer;
  7. class Subject
  8. {
  9. public:
  10.         virtual ~Subject();
  11.         virtual void addObserver(Observer* obsv);
  12.         virtual void removeOvserver(Observer* obsv);
  13.         virtual void notify();
  14.         virtual void addObserver(Observer_SecondVer* obsv);
  15.         virtual void removeOvserver(Observer_SecondVer* obsv);
  16.         virtual void notify_SecondVer();
  17.         virtual void addObserver(Observer_ThirdVer* obsv);
  18.         virtual void removeOvserver(Observer_ThirdVer* obsv);
  19.         virtual void notify_ThirdVer();
  20. private:
  21.         std::list<Observer *> mObserverList;
  22.         std::list<Observer_SecondVer*> mObserverList_SecondVer;
  23.         std::list<Observer_ThirdVer*> mObserverList_ThirdVer;
  24. };
复制代码
Subject.cpp
  1. void Subject::notify_SecondVer()
  2. {
  3.         std::list<Observer_SecondVer*>::const_iterator iter;
  4.         for (iter = mObserverList_SecondVer.begin(); iter != mObserverList_SecondVer.end(); ++iter)
  5.         {
  6.                 Observer_SecondVer* const curObsv = *iter;
  7.                 curObsv->update(this);
  8.         }
  9. }
  10. void Subject::notify_ThirdVer()
  11. {
  12.         std::list<Observer_ThirdVer*>::const_iterator iter;
  13.         for (iter = mObserverList_ThirdVer.begin(); iter != mObserverList_ThirdVer.end(); ++iter)
  14.         {
  15.                 Observer_ThirdVer* const curObsv = *iter;
  16.                 curObsv->update(this, std::string("有美女!"));
  17.         }
  18. }
复制代码
ConcreteSubjectA.h
  1. #pragma once
  2. #include "Subject.h"
  3. class ConcreteSubjectA :
  4.     public Subject
  5. {
  6. public:
  7.     void setState(bool b);
  8.     bool getState() const;
  9.     void setStateA(bool b);
  10.     bool getStateA() const;
  11.     void setStateB(bool b);
  12.     bool getStateB() const;
  13.     void changedState();
  14. private:
  15.     bool mSendToA = false;
  16.     bool mSendToB = false;
  17. };
复制代码
ConcreteSubjectA.cpp
  1. #include "ConcreteSubjectA.h"
  2. #include <iostream>
  3. void ConcreteSubjectA::setState(bool b)
  4. {
  5.         mSendToA = mSendToB = b;
  6.         changedState();
  7. }
  8. bool ConcreteSubjectA::getState() const
  9. {
  10.         return (mSendToA && mSendToB);
  11. }
  12. void ConcreteSubjectA::setStateA(bool b)
  13. {
  14.         std::cout << "美女来啦~" << std::endl;
  15.         mSendToA = b;
  16.         changedState();
  17. }
  18. bool ConcreteSubjectA::getStateA() const
  19. {
  20.         return mSendToA;
  21. }
  22. void ConcreteSubjectA::setStateB(bool b)
  23. {
  24.         std::cout << "刘亦菲来啦~" << std::endl;
  25.         mSendToB = b;
  26.         changedState();
  27. }
  28. bool ConcreteSubjectA::getStateB() const
  29. {
  30.         return mSendToB;
  31. }
  32. void ConcreteSubjectA::changedState()
  33. {
  34.         if (getStateA())
  35.         {
  36.                 notify_SecondVer();
  37.         }
  38.         else if (getStateB())
  39.         {
  40.                 notify_ThirdVer();
  41.         }
  42.         else if (getState())
  43.         {
  44.                 notify();
  45.                 notify_SecondVer();
  46.                 notify_ThirdVer();
  47.         }
  48.         else
  49.         {
  50.                 notify();
  51.         }
  52. }
复制代码
Observer.h
  1. #pragma once
  2. #include "Subject.h"
  3. class string;
  4. class Observer_ThirdVer // 响应固定主题 + 固定消息
  5. {
  6. public:
  7.         virtual ~Observer_ThirdVer() {}
  8.         virtual void update(Subject* subject, const std::string& info) = 0;
  9. };
复制代码
ConcreteObserverA.h
  1. #pragma once
  2. #include "Observer.h"
  3. class ConcreteObserverA_ThirdVer : public Observer_ThirdVer
  4. {
  5. public:
  6.     ConcreteObserverA_ThirdVer() {}
  7.     ConcreteObserverA_ThirdVer(Subject* subject);
  8.     virtual ~ConcreteObserverA_ThirdVer();
  9.     virtual void update(Subject* subject, const std::string& info) override;
  10. protected:
  11.     Subject* mSubject = nullptr;
  12. };
复制代码
ConcreteObserverA.cpp
  1. #include "ConcreteObserverA.h"
  2. #include <iostream>
  3. ConcreteObserverA_ThirdVer::ConcreteObserverA_ThirdVer(Subject* subject) : mSubject(subject)
  4. {
  5. }
  6. ConcreteObserverA_ThirdVer::~ConcreteObserverA_ThirdVer()
  7. {
  8.         if (mSubject)
  9.                 mSubject = nullptr;
  10. }
  11. void ConcreteObserverA_ThirdVer::update(Subject* subject, const std::string& info)
  12. {
  13.         if (subject && subject == mSubject)
  14.         {
  15.                 if (info == "有美女!")
  16.                 {
  17.                         std::cout << "哇~" << std::endl;
  18.                 }
  19.                 else
  20.                 {
  21.                         std::cout << "(ˉ▽ ̄~) 切~~" << std::endl;
  22.                 }
  23.         }
  24. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

麻花痒

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表