23种设计模式‑观察者(Observer)设计模式

发布时间:2026/10/1 15:37:46
23种设计模式‑观察者(Observer)设计模式
文章目录一.什么是观察者模式二.观察者模式的结构三.观察者模式的应用场景四.观察者模式的优缺点五.观察者模式的实现C示例六.观察者模式的实现JAVA示例七.代码解释八.总结类图观察者设计模式类图一.什么是观察者模式观察者模式Observer Pattern是一种行为型设计模式用于定义对象之间的一对多依赖关系。即一个对象称为“主题”Subject也叫被观察者状态发生改变时会自动通知依赖它的其他对象称为“观察者”Observer观察者收到通知后自动更新自身行为。这种模式在很多场景中都非常适用比如发布-订阅系统、事件监听、界面刷新等。观察者模式的核心特点是松耦合观察者和主题不需要彼此了解内部实现细节只需按照约定的接口进行交互这种设计大幅提升了代码的可维护性和可扩展性。二.观察者模式的结构Subject主题 / 被观察者又称被观察者用于存储和管理观察者列表定义注册、移除观察者的接口并在自身状态变化时遍历通知所有观察者。Observer观察者观察者抽象接口用于定义统一的更新方法所有具体观察者都必须实现该接口。ConcreteSubject具体主题继承/实现主题接口实现具体的状态管理以及状态变化时通知观察者的具体逻辑。ConcreteObserver具体观察者实现观察者接口接收主题的更新通知根据主题的新状态执行相应的业务行为。三.观察者模式的应用场景发布-订阅系统消息推送、内容订阅主题发布新内容时所有订阅者自动接收通知。GUI事件监听桌面/前端界面的按钮点击、键盘输入等事件组件状态变化触发监听者响应。数据联动刷新MVC架构中模型层数据变化后多视图面板自动同步刷新。配置中心同步分布式系统中配置中心更新后所有服务节点自动同步最新配置。监控告警系统监控指标异常时自动推送给多个告警渠道邮件、短信、即时通讯。四.观察者模式的优缺点优点主题与观察者深度解耦双方仅依赖抽象接口互不依赖具体实现新增任意一方都无需修改对方代码符合开闭原则。天然支持一对多广播主题状态变化时自动通知所有已注册观察者无需客户端手动逐个调用。动态灵活运行时可以随时注册、移除观察者不影响主题和其他观察者的运行。抽象层建立依赖在抽象层面定义对象联动关系适配不同的具体实现类。缺点通知效率随观察者数量下降观察者数量较多时遍历通知的耗时会线性增加。存在循环依赖风险若观察者同时也是主题互相观察可能触发循环通知导致系统异常。默认通知粒度粗原生通知仅告知“状态已变化”若需要传递具体变更内容需要额外设计参数协议。内存泄漏风险长生命周期的主题中观察者若未正确注销会一直被持有引用无法释放。五.观察者模式的实现C示例示例场景技术公众号具体主题发布文章所有关注的订阅用户具体观察者自动收到推送用户可随时关注/取消关注。#includeiostream#includevector#includestring#includealgorithmusingnamespacestd;// Observer抽象观察者接口classObserver{public:virtual~Observer()default;// 统一更新接口接收主题推送的状态virtualvoidupdate(conststringmessage)0;};// Subject抽象主题被观察者接口classSubject{public:virtual~Subject()default;virtualvoidattach(Observer*observer)0;// 注册观察者virtualvoiddetach(Observer*observer)0;// 移除观察者virtualvoidnotify()0;// 通知所有观察者};// ConcreteSubject具体主题 - 公众号classOfficialAccount:publicSubject{private:vectorObserver*observers;// 观察者列表string latestArticle;// 主题内部状态最新文章public:// 发布新文章状态变化触发通知voidpublishArticle(conststringtitle){latestArticletitle;cout\n公众号发布新文章《title》endl;notify();}voidattach(Observer*observer)override{observers.push_back(observer);}voiddetach(Observer*observer)override{autoitfind(observers.begin(),observers.end(),observer);if(it!observers.end()){observers.erase(it);}}voidnotify()override{for(Observer*obs:observers){obs-update(latestArticle);}}};// ConcreteObserver具体观察者 - 订阅用户classUser:publicObserver{private:string userName;public:User(string name):userName(name){}voidupdate(conststringmessage)override{cout用户【userName】收到推送messageendl;}};// 客户端测试代码intmain(){// 创建主题OfficialAccount*techBlognewOfficialAccount();// 创建观察者Observer*user1newUser(张三);Observer*user2newUser(李四);Observer*user3newUser(王五);// 注册观察者用户关注公众号techBlog-attach(user1);techBlog-attach(user2);techBlog-attach(user3);// 状态变化广播通知techBlog-publishArticle(详解观察者设计模式);// 移除观察者李四取消关注techBlog-detach(user2);cout\n李四取消关注公众号endl;// 再次状态变化仅通知剩余观察者techBlog-publishArticle(C设计模式实战);// 释放内存deleteuser1;deleteuser2;deleteuser3;deletetechBlog;return0;}C运行输出公众号发布新文章《详解观察者设计模式》 用户【张三】收到推送详解观察者设计模式 用户【李四】收到推送详解观察者设计模式 用户【王五】收到推送详解观察者设计模式 李四取消关注公众号 公众号发布新文章《C设计模式实战》 用户【张三】收到推送C设计模式实战 用户【王五】收到推送C设计模式实战六.观察者模式的实现JAVA示例importjava.util.ArrayList;importjava.util.List;// 抽象观察者interfaceObserver{voidupdate(Stringmessage);}// 抽象主题interfaceSubject{voidattach(Observerobserver);voiddetach(Observerobserver);voidnotifyObservers();}// 具体主题公众号classOfficialAccountimplementsSubject{privateListObserverobserversnewArrayList();privateStringlatestArticle;publicvoidpublishArticle(Stringtitle){this.latestArticletitle;System.out.println(\n公众号发布新文章《title》);notifyObservers();}Overridepublicvoidattach(Observerobserver){observers.add(observer);}Overridepublicvoiddetach(Observerobserver){observers.remove(observer);}OverridepublicvoidnotifyObservers(){for(Observerobs:observers){obs.update(latestArticle);}}}// 具体观察者用户classUserimplementsObserver{privateStringuserName;publicUser(Stringname){this.userNamename;}Overridepublicvoidupdate(Stringmessage){System.out.println(用户【userName】收到推送message);}}// 客户端publicclassObserverDemo{publicstaticvoidmain(String[]args){OfficialAccounttechBlognewOfficialAccount();Observeruser1newUser(张三);Observeruser2newUser(李四);Observeruser3newUser(王五);techBlog.attach(user1);techBlog.attach(user2);techBlog.attach(user3);techBlog.publishArticle(详解观察者设计模式);techBlog.detach(user2);System.out.println(\n李四取消关注公众号);techBlog.publishArticle(Java设计模式实战);}}七.代码解释Observer 抽象观察者定义统一的update()接口屏蔽不同观察者的业务差异主题只面向接口通知不需要知道具体观察者的类型和内部逻辑。Subject 抽象主题约定三个核心能力注册、移除、通知观察者是观察者模式解耦的核心主题仅依赖抽象观察者集合。ConcreteSubject 具体主题内部维护观察者列表持有自身业务状态当状态发生变化时调用notify()遍历所有观察者调用其update()方法完成广播。ConcreteObserver 具体观察者实现update()方法接收主题推送的状态执行自身的业务逻辑每个观察者独立处理通知互不影响。松耦合体现新增观察者类无需修改主题代码新增主题类也无需修改现有观察者两者完全通过抽象接口交互。八.总结观察者模式核心定义一对多的对象依赖主题状态变化时自动通知所有观察者实现触发式联动同时保持主题与观察者的松耦合。关键点归属行为型设计模式别名发布-订阅模式、源-监听器模式。四大角色抽象主题Subject、具体主题ConcreteSubject、抽象观察者Observer、具体观察者ConcreteObserver。核心优势解耦、一对多广播、动态增删观察者、符合开闭原则。适用场景事件驱动、消息推送、多视图同步、分布式配置同步等需要联动的场景。易混淆区分观察者是状态变化主动通知迭代器是客户端主动遍历访问。