重读设计模式——观察者
动机#
观察者模式意图建立一种对象间一对多的关系,当一个对象中的状态发生改变时,所有依赖它的对象都会收到通知并自动同步更新。
示例#
试想这样一种场景,有一组数据,可以通过不同的图表的方式被展示,比如柱状图、折线图、饼状图等等。虽然展示的方式不同,但数据应该是同样的一组,假设这组数据有一个数据对象关系,那么这个数据对象的任何改变都应该及时地在展示它的图表对象中同步改变。
class Subject;
class Observer {
public:
virtual ~Observer() = default;
virtual void update(Subject* changedobj) = 0;
protected:
Observer() = default;
};
class Subject {
public:
virtual ~Subject() = default;
virtual void attach(Observer* observer) {
m_observers.push_front(observer);
}
virtual void notify() {
for(auto observer : m_observers) {
observer->update(this);
}
}
protected:
explicit Subject(const std::string& name) : m_name(name) { }
private:
std::list<Observer*> m_observers{};
public:
std::string m_name;
};
class Data : public Subject {
public:
explicit Data(const std::string& name) : Subject(name) { };
void change() {
notify();
}
};
class PieChart : public Observer {
public:
void update(Subject* changedobj) {
cout << changedobj->m_name << " changed, PieChart update\n";
}
};
class BarChart : public Observer {
public:
void update(Subject* changedobj) {
cout << changedobj->m_name << " changed, BarChart update\n";
}
};
class LineChart : public Observer {
public:
void update(Subject* changedobj) {
cout << changedobj->m_name << " changed, LineChart update\n";
}
};
int main() {
Data data("data");
PieChart pie;
BarChart bar;
LineChart line;
data.attach(&pie);
data.attach(&bar);
data.attach(&line);
data.change();
return 0;
}
这里分别有饼状图、柱状图和折线图来展示同一组数据,使用被观察者的绑定方法,将图表绑定到数据上,当数据更新时,调用通知方式,让所有相关的图表对象更新。
执行结果:
data changed, LineChart update
data changed, BarChart update
data changed, PieChart update
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构