您的位置:首页 > 财经 > 产业 > 电脑怎么做软件开发_保定网站建设制作服务_统计工具_上海网站建设关键词排名

电脑怎么做软件开发_保定网站建设制作服务_统计工具_上海网站建设关键词排名

2024/12/22 1:16:54 来源:https://blog.csdn.net/FHKHH/article/details/144277406  浏览:    关键词:电脑怎么做软件开发_保定网站建设制作服务_统计工具_上海网站建设关键词排名
电脑怎么做软件开发_保定网站建设制作服务_统计工具_上海网站建设关键词排名

观察者模式(Observer Pattern)


定义

观察者模式是一种行为型设计模式,定义了一种 一对多的依赖关系,使得当一个对象的状态发生改变时,所有依赖它的对象都会收到通知并自动更新。


别名
  • 监听者模式(Listener Pattern)
  • 发布-订阅模式(Publish-Subscribe Pattern)

核心思想
  • 一对多依赖:一个主题对象(Subject)被多个观察者对象(Observer)订阅。
  • 事件通知:当主题对象发生状态改变时,会通知所有订阅它的观察者对象。
  • 解耦:主题对象和观察者对象之间松耦合,主题只负责通知,具体如何处理由观察者实现。

适用场景
  1. 系统中存在一对多的依赖关系
    • 多个模块需要依赖同一数据源。
  2. 需要动态订阅
    • 不确定具体哪些模块会对事件感兴趣。
  3. 事件驱动开发
    • 如 GUI 程序、消息通知机制。

类结构
  1. 主题(Subject)

    • 定义一个接口,用于添加、删除观察者对象。
    • 提供通知方法(如 notifyObservers())。
    • 维护观察者列表。
  2. 观察者(Observer)

    • 定义一个接口,实现更新方法(如 update())。
    • 用于处理主题的通知。
  3. 具体主题(ConcreteSubject)

    • 实现主题接口,维护主题的具体状态。
    • 当状态改变时通知观察者。
  4. 具体观察者(ConcreteObserver)

    • 实现观察者接口,根据通知做出响应。

代码实现
问题描述
  • 一个数据源(主题)被多个图表(观察者)订阅,当数据源发生变化时,需要通知所有图表更新。

完整代码
#include <iostream>
#include <vector>
#include <unordered_map>
#include <list>// 抽象观察者
class Observer {
public:virtual void handleMessage(int messageID) = 0;virtual ~Observer() = default;
};// 具体观察者1:观察者感兴趣的是消息 1 和 2
class Observer1 : public Observer {
public:void handleMessage(int messageID) override {if (messageID == 1 || messageID == 2) {std::cout << "Observer1 received message: " << messageID << std::endl;} else {std::cout << "Observer1 ignored message: " << messageID << std::endl;}}
};// 具体观察者2:观察者感兴趣的是消息 2
class Observer2 : public Observer {
public:void handleMessage(int messageID) override {if (messageID == 2) {std::cout << "Observer2 received message: " << messageID << std::endl;} else {std::cout << "Observer2 ignored message: " << messageID << std::endl;}}
};// 具体观察者3:观察者感兴趣的是消息 1 和 3
class Observer3 : public Observer {
public:void handleMessage(int messageID) override {if (messageID == 1 || messageID == 3) {std::cout << "Observer3 received message: " << messageID << std::endl;} else {std::cout << "Observer3 ignored message: " << messageID << std::endl;}}
};// 主题类
class Subject {
private:// 维护消息ID到观察者列表的映射std::unordered_map<int, std::list<Observer*>> observers;public:// 添加观察者void addObserver(int messageID, Observer* observer) {observers[messageID].push_back(observer);}// 通知观察者void notifyObservers(int messageID) {if (observers.find(messageID) != observers.end()) {for (Observer* observer : observers[messageID]) {observer->handleMessage(messageID);}} else {std::cout << "No observers for message: " << messageID << std::endl;}}
};// 主函数
int main() {Subject subject;Observer1 observer1;Observer2 observer2;Observer3 observer3;// 添加观察者subject.addObserver(1, &observer1);subject.addObserver(2, &observer1);subject.addObserver(2, &observer2);subject.addObserver(1, &observer3);subject.addObserver(3, &observer3);// 测试通知subject.notifyObservers(1); // 消息1通知subject.notifyObservers(2); // 消息2通知subject.notifyObservers(3); // 消息3通知subject.notifyObservers(4); // 无人订阅的消息return 0;
}

运行结果
Observer1 received message: 1
Observer3 received message: 1
Observer1 received message: 2
Observer2 received message: 2
Observer3 received message: 3
No observers for message: 4

代码解析
  1. 观察者接口(Observer)

    • 定义抽象方法 handleMessage,由具体观察者实现。
  2. 具体观察者(Observer1, Observer2, Observer3)

    • 每个观察者实现了 handleMessage,并根据感兴趣的消息 ID 处理事件。
  3. 主题类(Subject)

    • 维护了一个 unordered_map,将消息 ID 映射到感兴趣的观察者列表。
    • 提供 addObserver 添加观察者。
    • 提供 notifyObservers 方法,通知所有感兴趣的观察者。
  4. 运行逻辑

    • 消息 ID 为 1 时,通知 Observer1Observer3
    • 消息 ID 为 2 时,通知 Observer1Observer2
    • 消息 ID 为 3 时,通知 Observer3
    • 消息 ID 为 4 时,无观察者收到通知。

优缺点

优点

  1. 松耦合

    • 主题对象和观察者对象之间松耦合。
    • 主题不需要知道观察者的具体实现。
  2. 动态订阅

    • 可以动态添加、移除观察者。
  3. 扩展性好

    • 新增主题或观察者时,不需要修改已有代码。

缺点

  1. 性能问题

    • 如果观察者较多,通知开销可能较大。
  2. 过度依赖事件

    • 事件链较长时,可能导致难以追踪问题。

适用场景
  • GUI 事件处理:如按钮点击事件。
  • 发布-订阅系统:如消息队列。
  • 数据模型与视图同步:如 MVC 模式。

观察者模式与其他模式对比
模式用途关键特性
观察者模式监听状态变化,通知观察者一对多依赖
中介者模式通过中介者减少对象直接交互中心化协调
发布-订阅模式广播消息到多个订阅者更松散的关系,通常异步

总结
  1. 观察者模式的核心:解决一对多依赖问题,实现松耦合的事件通知机制。
  2. 实践建议:适用于动态订阅的场景,注意避免过多观察者导致性能问题。
  3. 应用范围:GUI、消息队列、实时数据更新等。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com