用C++实现观察者模式的几种变体
观察者模式的标准定义定义一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当这个主题对象的状态发生改变时,会关照所有观察者对象,使它们可以或许主动更新自己的状态。
观察者模式的标准结构图
https://i-blog.csdnimg.cn/direct/1bcdffb213ae48cc9f715eaf9442e264.png#pic_center
观察者模式的标准实现
Subject(抽象主题)
Subject.h
#pragma once
#include <list>
#include <string>
class Observer;
class Subject
{
public:
virtual ~Subject();
virtual void addObserver(Observer* obsv);
virtual void removeOvserver(Observer* obsv);
virtual void notify();
private:
std::list<Observer *> mObserverList;
};
Subject.cpp
#include "Subject.h"
#include "Observer.h"
Subject::~Subject()
{
if (!mObserverList.empty())
{
mObserverList.clear();
}
}
void Subject::addObserver(Observer* obsv)
{
if (nullptr == obsv)
return;
bool bExist = false;
std::list<Observer*>::const_iterator iter = mObserverList.begin();
for (; iter != mObserverList.end(); ++iter)
{
Observer* const curObsv = iter.operator*();
//*iter == obsv;
if (curObsv == obsv)
{
bExist = true;
break;
}
}
if (bExist)
return;
mObserverList.push_back(obsv);
}
void Subject::removeOvserver(Observer* obsv)
{
if (mObserverList.empty() || (nullptr == obsv))
return;
bool bExist = false;
std::list<Observer*>::const_iterator iter = mObserverList.begin();
for (; iter != mObserverList.end(); ++iter)
{
Observer* const curObsv = *iter;
if (curObsv == obsv)
{
bExist = true;
break;
}
}
if (bExist)
mObserverList.remove(obsv);
}
void Subject::notify()
{
std::list<Observer*>::const_iterator iter;
for (iter = mObserverList.begin(); iter != mObserverList.end(); ++iter)
{
Observer* const curObsv = *iter;
curObsv->update();
}
}
这里先说两个概念:原语函数、钩子函数
原语函数,即纯虚函数,意思就是必须在子类中重定义的函数;
钩子函数,即虚函数,意思是可以在子类中重定义的函数。
ConcreteSubject(具体主题)
ConcreteSubject.h
#pragma once
#include "Subject.h"
class ConcreteSubjectA :
public Subject
{
public:
void setState(bool b);
bool getState() const;
void changedState();
private:
bool mSendToA = false;
bool mSendToB = false;
};
ConcreteSubject.cpp
#include "ConcreteSubjectA.h"
#include <iostream>
void ConcreteSubjectA::setState(bool b)
{
mSendToA = mSendToB = b;
changedState();
}
bool ConcreteSubjectA::getState() const
{
return (mSendToA && mSendToB);
}
void ConcreteSubjectA::changedState()
{
std::cout << "刘亦菲来啦~" << std::endl;
if (getState())
{
notify();
}
}
Observer(抽象观察者)
Observer.h
#pragma once
class string;
class Observer
{
public:
Observer();
virtual ~Observer();
virtual void update() = 0;
};
Observer.cpp
#include "Observer.h"
Observer::Observer()
{
}
Observer::~Observer()
{
}
ConcreteObserverA(具体观察者A)
ConcreteObserverA.h
#pragma once
#include "Observer.h"
class ConcreteObserverA :
public Observer
{
public:
ConcreteObserverA();
~ConcreteObserverA();
virtual void update() override;
};
ConcreteObserver.cpp
#include "ConcreteObserverA.h"
#include <iostream>
ConcreteObserverA::ConcreteObserverA()
{
}
ConcreteObserverA::~ConcreteObserverA()
{
}
void ConcreteObserverA::update()
{
std::cout << "我要上报给领导!" << std::endl;
}
ConcreteObserverB(具体观察者B)
ConcreteObserverB.h
#pragma once
#include "Observer.h"
class ConcreteSubjectA;
class ConcreteObserverB :
public Observer
{
public:
ConcreteObserverB();
virtual ~ConcreteObserverB();
virtual void update() override;
};
ConcreteObserverB.cpp
#include "ConcreteObserverB.h"
#include "ConcreteSubjectA.h"
#include <iostream>
ConcreteObserverB::ConcreteObserverB()
{
}
ConcreteObserverB::~ConcreteObserverB()
{
}
void ConcreteObserverB::update()
{
std::cout << "我要通知其他人!" << std::endl;
}
主程序简单调用
#include "ConcreteObserverA.h"
#include "ConcreteSubjectA.h"
#include "ConcreteObserverB.h"
#include <iostream>
int main()
{
// Standard version
ConcreteObserverA* obsvA = new ConcreteObserverA();
ConcreteObserverB* obsvB = new ConcreteObserverB();
ConcreteSubjectA* subA = new ConcreteSubjectA();
subA->addObserver(obsvA);
subA->addObserver(obsvB);
subA->setState(true);
subA->removeOvserver(obsvB);
subA->removeOvserver(obsvA);
return EXIT_SUCCESS;
}
实在到这里,可以结束了;但是,好像又远远不敷。哪里不敷呢?
你难道不以为这两个观察者A、B有点太轻信于主题A了吗?不管谁给它们发消息,它们都相信 ,如许容易上当上当呀——说是刘亦菲来了,实在是刘姥姥来啦~。
观察者A、B也很委屈,腹诽道:我也不知道是谁给我的消息,我只知道,有消息,我就得做出反应;哪里还管得了你的、他的。
这还不简单…
观察者变身一
Observer.h
#pragma once
#include "Subject.h"
class Observer_SecondVer // 响应固定主题
{
public:
Observer_SecondVer();
Observer_SecondVer(Subject* subject);
virtual ~Observer_SecondVer();
virtual void update(Subject* subject = nullptr) = 0;
protected:
Subject* mSubject = nullptr;
};
ConcreteObserverA.h
#pragma once
#include "Observer.h"
class ConcreteObserverA_SecondVer : public Observer_SecondVer
{
public:
ConcreteObserverA_SecondVer();
ConcreteObserverA_SecondVer(Subject* subject);
~ConcreteObserverA_SecondVer();
virtual void update(Subject* subject = nullptr) override;
void doSomething();
};
ConcreteObserverA.cpp
#include "ConcreteObserverA.h"
#include <iostream>
ConcreteObserverA_SecondVer::ConcreteObserverA_SecondVer()
{
}
ConcreteObserverA_SecondVer::ConcreteObserverA_SecondVer(Subject* subject) : Observer_SecondVer(subject)
{
}
ConcreteObserverA_SecondVer::~ConcreteObserverA_SecondVer()
{
}
void ConcreteObserverA_SecondVer::update(Subject* subject)
{
if (subject && subject == mSubject)
{
doSomething();
}
}
void ConcreteObserverA_SecondVer::doSomething()
{
std::cout << "通知老板!" << std::endl;
}
ConcreteObserverB.h
#pragma once
#include "Observer.h"
class ConcreteSubjectA;
class ConcreteObserverB_SecondVer : public Observer_SecondVer
{
public:
ConcreteObserverB_SecondVer();
ConcreteObserverB_SecondVer(ConcreteSubjectA* subject);
~ConcreteObserverB_SecondVer();
virtual void update(Subject* subject = nullptr) override;
void doSomething();
};
ConcreteObserverB.cpp
#include "ConcreteObserverB.h"
#include "ConcreteSubjectA.h"
#include <iostream>
ConcreteObserverB_SecondVer::ConcreteObserverB_SecondVer()
{
}
ConcreteObserverB_SecondVer::ConcreteObserverB_SecondVer(ConcreteSubjectA* subject) : Observer_SecondVer(subject)
{
}
ConcreteObserverB_SecondVer::~ConcreteObserverB_SecondVer()
{
}
void ConcreteObserverB_SecondVer::update(Subject* subject)
{
if (subject && subject == mSubject)
{
doSomething();
}
}
void ConcreteObserverB_SecondVer::doSomething()
{
std::cout << "通知其他人!" << std::endl;
}
怎么样?以后,只要观察者A、B认定了主题A的消息,都进行相应,是不是就没那么容易上当上当了。
突然,观察者A又有点其他的想法,弱弱地问道:“那个~我不想只看刘亦菲,只要是美女,能不能都给我发消息呀?”
啊~ 你这~
于是乎…
主题变身一/二 + 观察者变身二
Subject.h
#pragma once
#include <list>
#include <string>
class Observer;
class Observer_SecondVer;
class Observer_ThirdVer;
class Subject
{
public:
virtual ~Subject();
virtual void addObserver(Observer* obsv);
virtual void removeOvserver(Observer* obsv);
virtual void notify();
virtual void addObserver(Observer_SecondVer* obsv);
virtual void removeOvserver(Observer_SecondVer* obsv);
virtual void notify_SecondVer();
virtual void addObserver(Observer_ThirdVer* obsv);
virtual void removeOvserver(Observer_ThirdVer* obsv);
virtual void notify_ThirdVer();
private:
std::list<Observer *> mObserverList;
std::list<Observer_SecondVer*> mObserverList_SecondVer;
std::list<Observer_ThirdVer*> mObserverList_ThirdVer;
};
Subject.cpp
void Subject::notify_SecondVer()
{
std::list<Observer_SecondVer*>::const_iterator iter;
for (iter = mObserverList_SecondVer.begin(); iter != mObserverList_SecondVer.end(); ++iter)
{
Observer_SecondVer* const curObsv = *iter;
curObsv->update(this);
}
}
void Subject::notify_ThirdVer()
{
std::list<Observer_ThirdVer*>::const_iterator iter;
for (iter = mObserverList_ThirdVer.begin(); iter != mObserverList_ThirdVer.end(); ++iter)
{
Observer_ThirdVer* const curObsv = *iter;
curObsv->update(this, std::string("有美女!"));
}
}
ConcreteSubjectA.h
#pragma once
#include "Subject.h"
class ConcreteSubjectA :
public Subject
{
public:
void setState(bool b);
bool getState() const;
void setStateA(bool b);
bool getStateA() const;
void setStateB(bool b);
bool getStateB() const;
void changedState();
private:
bool mSendToA = false;
bool mSendToB = false;
};
ConcreteSubjectA.cpp
#include "ConcreteSubjectA.h"
#include <iostream>
void ConcreteSubjectA::setState(bool b)
{
mSendToA = mSendToB = b;
changedState();
}
bool ConcreteSubjectA::getState() const
{
return (mSendToA && mSendToB);
}
void ConcreteSubjectA::setStateA(bool b)
{
std::cout << "美女来啦~" << std::endl;
mSendToA = b;
changedState();
}
bool ConcreteSubjectA::getStateA() const
{
return mSendToA;
}
void ConcreteSubjectA::setStateB(bool b)
{
std::cout << "刘亦菲来啦~" << std::endl;
mSendToB = b;
changedState();
}
bool ConcreteSubjectA::getStateB() const
{
return mSendToB;
}
void ConcreteSubjectA::changedState()
{
if (getStateA())
{
notify_SecondVer();
}
else if (getStateB())
{
notify_ThirdVer();
}
else if (getState())
{
notify();
notify_SecondVer();
notify_ThirdVer();
}
else
{
notify();
}
}
Observer.h
#pragma once
#include "Subject.h"
class string;
class Observer_ThirdVer // 响应固定主题 + 固定消息
{
public:
virtual ~Observer_ThirdVer() {}
virtual void update(Subject* subject, const std::string& info) = 0;
};
ConcreteObserverA.h
#pragma once
#include "Observer.h"
class ConcreteObserverA_ThirdVer : public Observer_ThirdVer
{
public:
ConcreteObserverA_ThirdVer() {}
ConcreteObserverA_ThirdVer(Subject* subject);
virtual ~ConcreteObserverA_ThirdVer();
virtual void update(Subject* subject, const std::string& info) override;
protected:
Subject* mSubject = nullptr;
};
ConcreteObserverA.cpp
#include "ConcreteObserverA.h"
#include <iostream>
ConcreteObserverA_ThirdVer::ConcreteObserverA_ThirdVer(Subject* subject) : mSubject(subject)
{
}
ConcreteObserverA_ThirdVer::~ConcreteObserverA_ThirdVer()
{
if (mSubject)
mSubject = nullptr;
}
void ConcreteObserverA_ThirdVer::update(Subject* subject, const std::string& info)
{
if (subject && subject == mSubject)
{
if (info == "有美女!")
{
std::cout << "哇~" << std::endl;
}
else
{
std::cout << "(ˉ▽ ̄~) 切~~" << std::endl;
}
}
}
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]