23种设计模式之观察者模式

ops/2024/12/12 5:35:55/

目录

  • 1. 简介
  • 2. 代码
    • 2.1 Subject
    • 2.2 ConcreteSubject
    • 2.3 Observer
    • 2.4 ConcreteObserver
    • 2.5 Test (测试)
    • 2.6 运行结果
  • 3. 优缺点
  • 4. 总结

1. 简介

观察者模式(Observer Pattern) 是一种行为设计模式。它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象的状态发生变化时,会通知所有的观察者对象,使它们能够自动更新自己的状态。
例如,在新闻发布系统中,新闻机构是主题(被观察对象),订阅新闻的用户是观察者。每当新闻机构发布一条新的新闻(主题状态改变),所有订阅的用户(观察者)都会收到通知,然后可以根据自己的需求来查看这条新闻。

结构:

  • 抽象主题(Subject)接口
    这个接口定义了添加、删除和通知观察者的方法。它是主题对象必须实现的接口,用于维护观察者列表并在状态改变时通知它们。
  • 具体主题(Concrete Subject)类
    具体主题类实现了抽象主题接口。它包含了可以被观察的状态,并且在状态发生变化时,通过调用通知方法来告知观察者。
  • 抽象观察者(Observer)接口
    抽象观察者接口定义了更新方法,当收到主题对象的通知时,观察者对象会调用这个方法来更新自己的状态。
  • 具体观察者(Concrete Observer)类
    具体观察者类实现了抽象观察者接口。它们根据主题对象通知的内容来执行具体的操作。

2. 代码

2.1 Subject

public interface Subject {void registerObserver(Observer observer);void removeObserver(Observer observer);void notifyObservers();
}

2.2 ConcreteSubject

import java.util.ArrayList;
import java.util.List;public class ConcreteSubject implements Subject{private List<Observer> observers = new ArrayList<>();private String state;public String getState() {return state;}public void setState(String state) {this.state = state;notifyObservers();}/** 绑定观察者*/@Overridepublic void registerObserver(Observer observer) {observers.add(observer);}/** 通知观察者*/@Overridepublic void notifyObservers() {for(Observer o : observers){o.update(state);}}/** 解绑观察者*/@Overridepublic void removeObserver(Observer observer) {observers.remove(observer);}
}

2.3 Observer

public abstract class Observer {protected String name;public abstract void update(String message);
}

2.4 ConcreteObserver

public class ConcreteObserver extends Observer{public ConcreteObserver(String name){this.name = name;}public void update(String message){System.out.println( name + "收到通知: " + message);}
}

2.5 Test (测试)

public class Test {public static void main(String[] args) {ConcreteSubject subject = new ConcreteSubject();Observer observer1 = new ConcreteObserver("观察者1");Observer observer2 = new ConcreteObserver("观察者2");subject.registerObserver(observer1);subject.registerObserver(observer2);subject.setState("状态1");subject.setState("状态2");}
}

2.6 运行结果

观察者1收到通知: 状态1
观察者2收到通知: 状态1
观察者1收到通知: 状态2
观察者2收到通知: 状态2

3. 优缺点

  • 观察者模式的优点
    • 松耦合
      主题和观察者之间是松耦合的关系。主题只需要知道观察者实现了更新方法,而不需要了解观察者的具体细节。同样,观察者也只需要实现更新方法来响应主题的通知,不需要知道主题内部是如何工作的。这种松耦合使得它们可以独立地变化和扩展。例如,在新闻系统中,可以很容易地添加新的用户设备(观察者)或者新的新闻发布平台(主题),而不会对现有的代码造成太大的干扰。
    • 支持广播通信
      一个主题对象的状态变化可以同时通知多个观察者对象,就像广播一样。这使得在需要将信息同时传递给多个接收者的场景中非常有效。例如,在股票交易系统中,股票价格的变化(主题状态变化)可以同时通知多个关注该股票的投资者(观察者)。
  • 观察者模式的缺点
    • 可能会导致性能问题
      如果有大量的观察者,当主题状态改变时,通知所有观察者可能会消耗较多的时间和资源。特别是在观察者的更新方法比较复杂或者涉及到网络通信等耗时操作时,这种性能问题会更加明显。例如,在一个大型的物联网系统中,一个传感器(主题)状态变化可能会通知大量的设备(观察者),如果设备的更新操作比较复杂,可能会导致系统响应变慢。
    • 可能会导致意外的更新循环
      如果在观察者的更新方法中又对主题对象进行了修改,可能会导致无限的更新循环。例如,在一个数据同步系统中,观察者在更新自己的状态后又修改了主题对象的状态,这可能会触发主题再次通知观察者,从而陷入无限循环。因此,在使用观察者模式时,需要谨慎设计更新逻辑,避免这种情况的发生。

4. 总结

观察者模式是一种重要的设计模式,通过解耦对象间的依赖关系,提高了系统的灵活性和可扩展性。然而,在使用时需要注意避免过度复杂的设计以及潜在的性能问题。合理设计观察者数量和优化通知机制是确保系统高效运行的关键。


http://www.ppmy.cn/ops/141172.html

相关文章

最近邻搜索 - 经典树型结构 M-Tree

前言 如果你对这篇文章感兴趣&#xff0c;可以点击「【访客必读 - 指引页】一文囊括主页内所有高质量博客」&#xff0c;查看完整博客分类与对应链接。 最近邻搜索的目标是从 N N N 个对象中&#xff0c;快速找到距离查询点最近的对象。根据需求的不同&#xff0c;该任务又分…

MAVEN--Maven的生命周期,pom.xml详解,Maven的高级特性(模块化、聚合、依赖管理)

目录 &#xff08;一&#xff09;Maven的生命周期 1.Maven的三套生命周期 2.Maven常用命令 &#xff08;二&#xff09;pom.xml详解 &#xff08;三&#xff09;Maven的高级特性&#xff08;模块化、聚合、依赖管理&#xff09; 1.Maven的依赖范围 2.版本维护 3.依赖传…

无人机飞手考证后从事吊运植保创业技术详解

无人机飞手考证后从事吊运植保创业的技术详解如下&#xff1a; 一、无人机飞手考证流程 1. 报名与资格审核&#xff1a; 选择正规培训机构&#xff0c;提交身份证明、学历证明等相关材料。 通过初步审核&#xff0c;确保学员满足年龄&#xff08;年满16周岁&#xff09;、身…

CGM:卡与应用内存管理

内存资源管理 1. 管理概述 1.1 可选功能说明 1.2 管理主体责任 2. 资源分配规则 2.1 加载时分配 2.1.1 最小内存要求 2.1.2 资源可用性检查 2.2安装时分配 2.2.1 内存配额设定 2.2.2 预留内存处理 3. 资源使用管理 3.1 应用运行时分配 3.1.1 数据存储分配 3.1.2 资源耗尽处理 3…

QT 中 QDateTime::currentDateTime() 输出格式备查

基础 QDateTime::currentDateTime() //当前的日期和时间。 QDateTime::toString() //以特定的格式输出时间&#xff0c;格式 yyyy: 年份&#xff08;4位数&#xff09; MM: 月份&#xff08;两位数&#xff0c;07表示七月&#xff09; dd: 日期&#xff08;两位数&#xff0c…

2024小迪安全基础入门第十一课

目录 一、算法识别加解密-MD5&AES&DES&RSA #算法加密-概念&分类&类型 二、 解密条件-有源码找逻辑&无源码JS逆向 #加密解密-识别特征&解密条件 #密码存储 一、算法识别加解密-MD5&AES&DES&RSA 安全测试中&#xff1a; 密文-有源…

ARM学习(36)静态扫描规则学习以及工具使用

笔者来学习了解一下静态扫描以及其规则&#xff0c;并且亲身是实践一下对arm 架构的代码进行扫描。 1、静态扫描认识 静态扫描&#xff1a;对代码源文件按照一定的规则进行扫描&#xff0c;来发现一些潜在的问题或者风险&#xff0c;因为不涉及代码运行&#xff0c;所以其一般…

网管平台(基础篇):路由器的介绍与管理

路由器简介 路由器&#xff08;Router&#xff09;是一种计算机网络设备&#xff0c;它的主要作用是将数据通过打包&#xff0c;并按照一定的路径选择算法&#xff0c;将网络传送至目的地。路由器能够连接两个或更多个网络&#xff0c;并根据信道的情况自动选择和设定路由&…