当前位置: 首页 > news >正文

17.行为型 - 观察者模式 (Observer Pattern)

观察者模式 (Observer Pattern)

意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

主要解决:一个对象状态改变其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作

举一个例子:比如用户从报社订阅报纸报社用户之间是一对多依赖,用户可以在报社订阅(register)报纸,报社可以把最新的报纸发给用户(notify),用户自动收到更新。在用户不需要的时候还可以取消注册(remove)。

UML类图

Pasted image 20231130215621

代码实例

1.被观察的抽象和实现 (报社)

被观察者

public interface Subject {
//被观察者的几个方法, public void registerObserver(Observer observer);//订阅public void removeObserver(Observer observer);//取消订阅public void notifyObserver();//通知 观察者
}

被观察者实现

//被观察者实现 (报社)
public class Newspaper implements Subject {private Date time;private String category;private String content;List<Observer> userList;//初始化public Newspaper() {userList = new ArrayList<Observer>();}public void registerObserver(Observer observer) {userList.add(observer);}public void notifyObserver() {for (Observer ob : userList) {ob.receive(time,category,content);}}public void removeObserver(Observer observer) {int index = userList.indexOf(observer);userList.remove(index);}public void setNewspaper(Date time, String category, String content) {this.time = time;this.category = category;this.content = content;notifyObserver();}
}

2.观察者的抽象和实现 (用户)

观察者

public interface Observer {//观察者接收信息的方法(三个参数分别对应时间,分类,内容)public void receive(Date time, String category, String content);
}

观察者实现

//用户类
public class User implements Observer {private Date time;private String category;private String content;public void receive(Date time, String category, String content) {this.time = time;this.category = category;this.content = content;toString()}public String toString() {return "time:"+ time + " " + "category:" + category + " " + "content:" + content + " ";}
}

3.测试

public static void main(String[] args) {Newspaper news = new Newspaper();//报社 被观察者User user1 = new User();User user2 = new User();news.registerObserver(user1);//用户1 向报社订阅news.registerObserver(user2);//用户2 向报社订阅//报社(一方) 通知 订阅者(多方) 有新的新闻内容了news.setNews(new Date(), "娱乐", "海绵宝宝获得了奥斯卡奖");
}

观察者模式(Observer Pattern)总结

关键角色

  1. 被观察者(抽象)
  2. 被观察者实现
  3. 观察者(抽象)
  4. 观察者实现

观察者模式的优缺点

1) 观察者模式的优点

  • 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。
  • 被观察者发送通知,所有注册的观察者都会收到信息【可以实现广播机制】

2) 观察者模式的缺点

  • 如果观察者非常多的话,那么所有的观察者收到被观察者发送的通知会耗时
  • 如果被观察者有循环依赖的话,那么被观察者发送通知会使观察者循环调用,会导致系统崩溃

观察者模式适用场景

  • 当一个对象状态的改变需要改变其他对象时。比如,商品库存数量发生变化时,需要通知商品详情页、购物车等系统改变数量。
  • 一个对象发生改变时只想要发送通知,而不需要知道接收者是谁。比如,订阅微信公众号的文章,发送者通过公众号发送,订阅者并不知道哪些用户订阅了公众号。
  • 需要创建一种链式触发机制时。比如,在系统中创建一个触发链,A 对象的行为将影响 B 对象,B 对象的行为将影响 C 对象……这样通过观察者模式能够很好地实现。
  • 微博或微信朋友圈发送的场景。这是观察者模式的典型应用场景,一个人发微博或朋友圈,只要是关联的朋友都会收到通知;一旦取消关注,此人以后将不会收到相关通知。
  • 需要建立基于事件触发的场景。比如,基于 Java UI 的编程,所有键盘和鼠标事件都由它的侦听器对象和指定函数处理。当用户单击鼠标时,订阅鼠标单击事件的函数将被调用,并将所有上下文数据作为方法参数传递给它。

在JDK 中对观察者模式的支持

JDK中提供了 Observable 类以及 Observer接口, 它们构成了JDK对观察者模式的支持.

观察者

  • java.util.Observer 接口: 该接口中声明了一个方法,它充当抽象观察者,其中声明了一个update方法.
void update(Observable o, Object arg);

被观察者

  • java.util.Observable 类: 充当观察目标类(被观察类) , 在该类中定义了一个Vector集合来存储观察者对象.下面是它最重要的 3 个方法。
  • void addObserver(Observer o) 方法:用于将新的观察者对象添加到集合中。
  • void notifyObservers(Object arg) 方法:调用集合中的所有观察者对象的 update方法,通知它们数据发生改变。通常越晚加入集合的观察者越先得到通知。
  • void setChange()方法:用来设置一个 boolean 类型的内部标志,注明目标对象发生了变化。当它为true时,notifyObservers() 才会通知观察者。

用户可以直接使用Observer接口和Observable类作为观察者模式的抽象层,再自定义具体观察者类和具体观察目标类,使用JDK中提供的这两个类可以更加方便的实现观察者模式.

http://www.jsqmd.com/news/111442/

相关文章:

  • 云原生热点聚焦:OpenTofu 1.11.0 发布与关键工具更新
  • GitCode项目创建分支并提交代码
  • Bitcraze介绍
  • 修改 OBS-Studio 的字体
  • Linux上位机Windows上位机C++(QT)开发三菱上位机MC 1E 二进制通信 源码 C++快速实现三菱 MC 1E 二进制 支持三菱FX和A系列PLC A-1E 帧 国产化系统上位机
  • SIGSEGV段错误排查全攻略
  • EtherCAT核心术语DPRAM/FMMU/SM通俗解析
  • AI元人文构想的理论构建过程与深层意义分析(二)
  • P4171 [JSOI2010] 满汉全席
  • dotnet未捕获异常导致系统崩溃问题
  • Scikit-Learn 1.8引入 Array API,支持 PyTorch 与 CuPy 张量的原生 GPU 加速
  • Day33PC与移动端的适配方案简介
  • 无代码解决方案:解锁数字化转型的普惠路径
  • 【Agent】MemOS 源码笔记---(6)---MemScheduler -- 总体
  • 震惊!IF9.8,中科院1区TOP或被SCI剔除!官网已“消失”......
  • 杂乱的一些note
  • 21、Samba使用与故障排查全解析
  • C++输入输出(cin和cout)的用法
  • 深入理解Golang并发模型与CSP理论
  • Oracle索引技术:理论与实操全解析
  • 23、Samba使用与SSL配置全解析
  • 三菱PLC与组态王打造饮料自动装箱机控制系统
  • 【Nature Communications‘24‘06】预训练多模态大语言模型经过 SkinGPT-4 提升皮肤病学诊断能力
  • 品牌营销战略策划公司选哪家靠谱?奇正沐古 - 资讯焦点
  • 100 天学会爬虫 · Day 12:为什么要给爬虫加随机 User-Agent?原理与实战
  • 宪法守护童年:向霸凌和诈骗说“不” - 资讯焦点
  • 2025年郑州头部吊顶式空调机组设计多少钱,空气幕/表冷器/卧式暗装风机盘管/吊顶式空调机组/工业暖风机吊顶式空调机组采购找哪家 - 品牌推荐师
  • RUI Builder-图形化UI设计-工程范例
  • argocd-案例
  • 探秘新能源整车动力性经济性仿真模型:精确模拟驱动未来出行