18行为型设计模式——观察者模式
一、观察者模式简介
观察者模式(Observer Pattern)是一种行为设计模式,它定义了一种一对多的依赖关系,使得当一个对象的状态发生变化时,其相关依赖对象会自动收到通知并更新。这个模式常用于实现分布式事件处理系统。比如Windows系统更新、手机软件更新。
GoF一书中对观察者模式的介绍
- 被观察者(Subject):这是状态发生变化的对象,它维护一个观察者列表并提供方法来附加、移除和通知观察者。
- 观察者(Observer):这是对状态变化做出反应的对象,它通常有一个更新接口,允许被观察者调用这个接口来通知状态变化。
Subject和Observer都是面向接口编程,因此具有自己的具体实现类。
二、观察者模式设计方法
设计一个模拟手机应用程序更新的观察者模式,模拟实现一个 C++ 系统,其中Subject代表手机系统的更新管理程序(应用商店),Observer代表手机中的各个应用程序(APP),代码如下。
observer.cpp
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>// 抽象观察者
class Observer {
public:virtual ~Observer() = default;virtual bool update(const std::string& app, const std::string& updateInfo) = 0;
};// 抽象被观察者
class Subject {
public:virtual ~Subject() = default;void attach(Observer* observer) {observers.push_back(observer);}void notify(const std::string& app, const std::string& updateInfo) {bool notified = false;for (Observer* observer : observers) {if (observer->update(app, updateInfo)) {notified = true;} }if (!notified) {std::cout << app << "已更新到最新版本," << updateInfo << std::endl;}}private:std::vector<Observer*> observers;
};// 具体被观察者
class UpdateManager : public Subject {
public:void checkUpdates() {//模拟检查到更新std::cout << " 应用商店: 最新上架新版本的《黑神话·悟空》手游,版本号2024.08.23." <<std::endl;std::cout << " 应用商店: 最新上架新版本的《英雄联盟》手游,版本号2024.08.23." <<std::endl;std::cout << " 应用商店: 最新上架新版本的《王者荣耀》手游,版本号2024.08.23." <<std::endl;std::cout << " 应用商店: 最新上架新版本的《百词斩》学习机,版本号2024.08.23." <<std::endl;std::cout << " 应用商店: 最新上架新版本的《个人所得税》,版本号2024.08.23." <<std::endl;std::cout << " 应用商店: 最新上架新版本的《csdn》,版本号2024.08.23.\n" <<std::endl;// 触发通知手机APPnotify("《黑神话·悟空》", "最新版本号2024.08.23");notify("《英雄联盟》", "最新版本号2024.08.23");notify("《王者荣耀》", "最新版本号2024.08.23");notify("《百词斩》", "最新版本号2024.08.23");notify("《个人所得税》", "最新版本号2024.08.23");notify("《csdn》", "最新版本号2024.08.23");}
};// 具体观察者
class Applications : public Observer {
public:Applications(const std::string& app) : app(app) {}bool update(const std::string& app, const std::string& updateInfo) override {if (this->app == app) {std::cout << " 应用软件 " << app << " ,收到更新通知:" << updateInfo <<std::endl;return true;}return false;}private:std::string app;
};int main () {// 模拟手机端已安装的APPUpdateManager updatemanager;Applications app1("《黑神话·悟空》");Applications app2("《英雄联盟》");Applications app3("王者荣耀");Applications app4("《百词斩》");Applications app5("《个人所得税》");Applications app6("csdn");updatemanager.attach(&app1);updatemanager.attach(&app2);updatemanager.attach(&app3);updatemanager.attach(&app4);updatemanager.attach(&app5);updatemanager.attach(&app6);// 模拟应用商店检查更新updatemanager.checkUpdates();return 0;
}
运行效果
三、观察者模式的应用场景
1. 事件处理系统
在图形用户界面(GUI)设计中,观察者模式通常用于处理用户事件。例如,当用户点击按钮时,按钮的点击事件会通知所有注册的事件监听器(观察者),以便执行相应的操作。
2. 消息通知系统
消息通知系统(如新闻订阅、社交媒体通知)可以使用观察者模式来处理消息的发布和订阅。当消息发布者(主题)发布新消息时,所有订阅者(观察者)都会收到通知并进行处理。
3. 数据绑定
在数据绑定(如在MVVM模式中的数据绑定)中,观察者模式用于自动更新视图(观察者)以反映模型(主题)的变化。当模型数据发生变化时,视图会自动更新以展示最新的数据。
4. 实时数据监控
在实时数据监控系统中,如股票价格监控、天气数据监控,观察者模式可以用于通知用户(观察者)实时数据的变化。例如,当股票价格发生变化时,所有监控该股票的用户都会收到更新通知。
5. 日志系统
日志系统中可以使用观察者模式将日志消息(主题)分发到多个处理器(观察者),如控制台输出、文件记录、远程日志服务器等。每个处理器都可以独立地处理日志消息。
6. 聊天应用
在聊天应用中,观察者模式可以用于实现消息的广播。每当一个用户发送消息时,所有在同一聊天房间的用户(观察者)都会收到该消息。
7. 插件系统
在插件系统中,主程序(主题)可以通知所有已安装的插件(观察者)某些事件的发生。例如,当程序更新或某个功能被触发时,所有相关的插件可以做出响应。
8. 模型-视图-控制器(MVC)
在MVC架构中,模型(数据层)作为主题,视图(用户界面层)作为观察者。当模型数据变化时,视图会自动更新以反映这些变化,从而实现数据和视图的解耦。
9. 分布式系统
在分布式系统中,观察者模式用于实现分布式系统组件间的通知和数据同步。例如,当一个组件的数据发生变化时,所有依赖于这些数据的其他组件都会得到更新通知。
四、总结
观察者模式的核心优势在于它能够减少对象之间的耦合性,使得系统更具扩展性和灵活性。其主要用于处理对象之间的依赖关系,使得当一个对象的状态发生变化时,所有依赖于它的对象都会自动得到通知并更新。这个模式非常适合于那些一对多依赖关系的场景。