网站开发需求预算,建筑工程网教育网,长沙网站建设kaodezhu,大资讯wordpress主题1. 意图 定义对象间的一种一对多的依赖关系#xff0c;当一个对象的状态发生改变时#xff0c;所有依赖于它的对象都得到通知并被自动更新。 在观察者模式中#xff0c;有两类对象#xff1a;被观察者#xff08;Subject#xff09;和观察者#xff08;Observer#xf…1. 意图 定义对象间的一种一对多的依赖关系当一个对象的状态发生改变时所有依赖于它的对象都得到通知并被自动更新。 在观察者模式中有两类对象被观察者Subject和观察者Observer。被观察者是一个具有状态的对象当其状态发生变化时会通知所有的观察者。观察者是一个依赖于被观察者的对象它会接收到被观察者的通知并进行相应的处理。
2. 适用性 《GOF设计模式:可复用面向对象软件的基础》中描述如下
当一个抽象模型有两方面其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们各自独立地自主改变和复用。当对一个对象的改变需要同时改变其它对象而不知道具体有多少对象有待改变。当一个对象必须通知其它对象而它又不能假定对象是谁。即对象之间关系是解耦合的。
3. 实现
#include iostream
#include string
#include vectorclass Observer {
public:virtual ~Observer() {}virtual void Update(const std::string msg) 0;
};class NetObserver : public Observer {
public:virtual void Update(const std::string msg) override {std::cout NetObserver recv msg: msg std::endl;}
};class SerialObserver : public Observer {
public:virtual void Update(const std::string msg) override {std::cout SerialObserver recv msg: msg std::endl;}
};class Subject {
public:virtual ~Subject() {}bool Attach(Observer *ptr) {if (ptr nullptr)return false;m_vecObserver.push_back(ptr);return true;}void Detach(const Observer *ptr) {for (auto iter m_vecObserver.begin(); iter ! m_vecObserver.end();iter) {if (*iter ! ptr)continue;m_vecObserver.erase(iter);}}void Notify(const std::string msg) {for (Observer *ptr : m_vecObserver)ptr-Update(msg);}private:std::vectorObserver * m_vecObserver;
};class NetSubject : public Subject {
public:void DoSomething() { Notify(NetSubject msg); }
};class SerialSubject : public Subject {
public:void DoSomething() { Notify(SerialSubject msg); }
};void Test() {NetObserver *net1 new NetObserver;NetObserver *net2 new NetObserver;SerialObserver *serial1 new SerialObserver;SerialObserver *serial2 new SerialObserver;NetSubject *netSub new NetSubject;SerialSubject *serialSub new SerialSubject;netSub-Attach(net1);netSub-DoSomething();std::cout ------------------------------ std::endl;netSub-Attach(net2);netSub-DoSomething();std::cout ------------------------------ std::endl;serialSub-Attach(serial1);serialSub-DoSomething();std::cout ------------------------------ std::endl;serialSub-Attach(serial2);serialSub-DoSomething();delete net1;delete net2;delete serial1;delete serial2;delete netSub;delete serialSub;
}int main() {Test();return 0;
}
执行结果
NetObserver recv msg: NetSubject msg ------------------------------ NetObserver recv msg: NetSubject msg NetObserver recv msg: NetSubject msg ------------------------------ SerialObserver recv msg: SerialSubject msg ------------------------------ SerialObserver recv msg: SerialSubject msg SerialObserver recv msg: SerialSubject msg
4. 优缺点 松耦合性被观察者和观察者之间是松耦合的它们之间仅通过接口或抽象类进行通信不需要直接相互引用可以独立变化。 可扩展性可以随时增加新的观察者而不需要修改被观察者的代码也可以很容易地添加新的被观察者。 可重用性观察者模式可以在不同的场景中重复使用不需要重写逻辑。 实时更新被观察者一旦发生变化所有的观察者都会实时收到通知并进行相应的更新保证了数据的实时性。 观察者过多如果观察者的数量过多通知所有观察者可能会导致性能问题影响系统的运行效率。 顺序控制困难观察者之间是一种松散的耦合关系无法控制观察者接收通知的顺序可能会导致一些不可预测的问题。 循环依赖问题如果观察者与被观察者之间存在循环依赖可能会导致系统出现问题。
5. 模板实现
#include functional
#include iostream
#include string
#include unordered_mapclass ObserverA {
public:void UpdateA(const std::string msg) {std::cout ObserverA msg: msg std::endl;}
};class ObserverB {
public:void UpdateB(const std::string msg) {std::cout ObserverB msg: msg std::endl;}
};template typename Func class Event {
public:Event() : m_observeId(0) {}virtual ~Event() {}int Attach(Func f) { return Assign(f); }int Attach(const Func f) { return Assign(f); }void Detach(int key) { m_mapOberserve.erase(key); }template typename... Args void Notify(Args ...args) {for (auto it : m_mapOberserve) {it.second(std::forwardArgs(args)...);}}private:Event(const Event ) delete;Event operator(const Event ) delete;template typename F int Assign(F f) {m_mapOberserve.emplace(m_observeId, std::forwardF(f));return m_observeId - 1;}private:int m_observeId;std::unordered_mapint, Func m_mapOberserve;
};
void Test() {Eventstd::functionvoid(const std::string ) event;ObserverA oba;int key event.Attach(std::bind(ObserverA::UpdateA, oba, std::placeholders::_1));event.Notify(AAAAA);std::cout ----------------------- std::endl;ObserverB obb;event.Attach(std::bind(ObserverB::UpdateB, obb, std::placeholders::_1));event.Notify(AAAAABBBBB);std::cout ----------------------- std::endl;event.Detach(key);event.Notify(BBBBB);
}int main() {Test();return 0;
}
执行输出
ObserverA msg: AAAAA ----------------------- ObserverB msg: AAAAABBBBB ObserverA msg: AAAAABBBBB ----------------------- ObserverB msg: BBBBB