C++观察者模式
代码实现如下
cpp
#include <iostream>
#include <memory>
#include <vector>
#include <algorithm>
using namespace std;
//抽象观察者类
class Observer {
public:
virtual ~Observer() = default;
//更新观察者
virtual void update(int state) = 0;
};
//抽象主题类
class Subject {
public:
virtual ~Subject() = default;
//注册观察者
virtual void attach(std::shared_ptr<Observer> observer) = 0;
//移出观察者
virtual void detach(std::shared_ptr<Observer> observer) = 0;
//通知所有观察者
virtual void notify() = 0;
//获取主题状态
virtual int getState() const = 0;
//设置主题状态
virtual void setState(int state) = 0;
};
class ConcreteSubject : public Subject {
public:
ConcreteSubject() :state(0) {
}
//添加
void attach(std::shared_ptr<Observer> observer)override {
observerVec.push_back(observer);
}
//移出
void detach(std::shared_ptr<Observer> observer) override {
auto it = std::find(observerVec.begin(), observerVec.end(), observer); //使用算法先查找,然后移出效率更高效
if (it != observerVec.end())
{
observerVec.erase(it);
}
}
//通知所有已经注册的观察者对象
void notify() override
{
for (const auto& obser : observerVec)
{
obser->update(state);
}
}
int getState() const override{
return state;
}
void setState(int _state) {
state = _state;
notify();
}
private:
int state;
std::vector<std::shared_ptr<Observer>> observerVec;
};
class ConcreteObserver:public Observer {
public:
ConcreteObserver(const std::string& _name) :observerState(0), name(_name) {};
void update(int state) override {
observerState = state;
display();
}
void display() const
{
std::cout << "通知 " << name << " 更新了状态为 " << observerState << std::endl;
}
private:
int observerState;
std::string name;
};
int main()
{
//创建主题
std::shared_ptr<ConcreteSubject> subject = std::make_shared<ConcreteSubject>();
//创建观察者
std::shared_ptr<ConcreteObserver> observer1 = std::make_shared<ConcreteObserver>("观察者1");
std::shared_ptr<ConcreteObserver> observer2 = std::make_shared<ConcreteObserver>("观察者2");
//注册观察者
subject->attach(observer1);
subject->attach(observer2);
subject->setState(1);
subject->detach(observer2);
std::cout << std::endl;
subject->setState(2);
return 0;
}
UML图如下
观察者模式即一个观察者状态改变后,会通知内部已经注册的观察者对象改变状态,实现状态的改变。
观察者模式使用抽象基类的方法遵循了依赖颠倒原则,同时有新的具体观察者和新的具体主题时都可以进行动态扩展,符合开闭原则。但是观察者模式也存在不方便。比如在界面中使用观察者模式,点击按钮后,关闭原有的图片,显示一张新的图片,这样的两个操作,一个是close(),一个是show(),或者更多的操作,也就是说和抽象观察者中留的接口不同了。还有一个更好的实现方式,委托。