观察者模式
观察者模式的优缺点
优点
- 当一个对象改变的时候 需要同时改变其他对象的相关动作的时候 ,而且它不知道有多少具体的对象需要改变 应该考虑使用观察者模式 。
- 观察者模式的工作就是解除耦合 让耦合双方都依赖与抽象 而不是具体 是的各自改变都不会影响另一边工作
缺点
- 具体的观察类里面的update方法太单调了 现实是每个观察者的动作都可能都所不同
可以使用两种方式去解决此类问题
1:具体的观察者实现具体的 自己需要完成的任务 在继承抽象Observer后 在update内部直接调用具体的方式
2:具体的观察者将自己具体的动作也同时注册到 通知类里面 改变通知类里面的容器为map容器类 key为具体的观察者 value为具体的处理函数
代码
只实现基础部分
cpp
#include <iostream>
#include <set>
using namespace std;
// 抽象观察者
class Observer {
public:
virtual void update(const string& subjectState) = 0;
};
// 抽象主题
class Subject {
public:
virtual void Attach(Observer* observer) = 0;
virtual void Detach(Observer* observer) = 0;
virtual void Notify(const string& state) = 0;
virtual string GetSubjectState() const = 0;
virtual void SetSubjectState(const string& state) = 0;
};
// 具体主题
class ConcreteSubject : public Subject {
public:
void Attach(Observer* observer) override {
observers.insert(observer);
}
void Detach(Observer* observer) override {
observers.erase(observer);
}
void Notify(const string& state) override {
for (auto observer : observers) {
observer->update(state);
}
}
string GetSubjectState() const override {
return subjectState;
}
void SetSubjectState(const string& state) override {
subjectState = state;
Notify(subjectState); // 当状态改变时,通知所有观察者
}
private:
set<Observer*> observers;
string subjectState;
};
// 具体观察者
class ConcreteObserver : public Observer {
public:
ConcreteObserver(const string& name, const string& initialState)
: name(name), observerState(initialState) {}
void update(const string& subjectState) override {
observerState = subjectState;
cout << "观察者: " << name << " 的新状态是 " << observerState << endl;
}
private:
string name;
string observerState;
};
int main() {
ConcreteSubject* s = new ConcreteSubject();
s->Attach(new ConcreteObserver("小明", "松懈"));
s->Attach(new ConcreteObserver("蔡徐坤", "松懈"));
// 改变主题状态,这将触发通知
s->SetSubjectState("警惕");
return 0;
}