观察者模式(Observer Pattern)

观察者模式简介 创建一个具体主题类(ConcreteSubject),该类继承自主题类,在具体主题中定义了相应的业务逻辑,并在合适的时机通过调用触发事件方法来通知所有注册的观察者。最后,在使用示例中,我们创建了一个具体主题对象和两个具体观察者对象,并将观察者注册到主题上。创建具体的主题类(ConcreteSubject),该类维护了一个观察者列表,并在状态改变时遍历通知所有注册的观察者。最后,我们创建了具体的观察者类。主题和观察者都实现相应接口,在主题中维护一个观察者列表,并在状态改变时遍历通知所有观察者。 阅读详情

一、什么是观察者模式

观察者模式是一种对象行为模式。它定义对象间的一种一对多的依赖关系,当一个对象(目标对象)的状态发生改变时,所有依赖于它的对象(观察对象)都得到通知并被自动更新。特点:被观察者和观察者一般是一对多的关系,一个被观察者对应多个观察者,当一个被观察者的状态发生改变时,被观察者通知观察者,然后可以在观察者内部进行业务逻辑的处理。

JDK 提供了 一套观察者模式的实现,在java.util包中, java.util.Observable类和java.util.Observer接口。Observable 是被观察者,Observer 是观察者。

在观察者模式中,主题是通知的发布者,它发出通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅并接收通知。观察者模式不仅被广泛应用于软件界面元素之间的交互,在业务对象之间的交互、权限管理等方面也有广泛的应用。

面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情,并且将其做好。观察者模式完美的将观察者和被观察的对象分离开,在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。

观察者模式,又叫发布-订阅模式(Publish/Subscribe Pattern)。UML 结构图如下:

1️⃣【主题 Subject通知的发布者】它把所有对观察者对象的引用文件存在了一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供了一个接口,可以增加和删除观察者对象。

首先定义一个观察者数组,并实现增、删及通知操作。它的职责很简单,就是定义谁能观察,谁不能观察,用 Vector 是线程同步的,比较安全,也可以使用 ArrayList,是线程异步的,但不安全。

public class Subject {
    //观察者数组
    private Vector<Observer> oVector = new Vector<>();
    //增加一个观察者
    public void addObserver(Observer observer) {
        this.oVector.add(observer);
    }
    //删除一个观察者
    public void deleteObserver(Observer observer) {
        this.oVector.remove(observer);
    }
    //通知所有观察者
    public void notifyObserver() {
        for(Observer observer : this.oVector) {
            observer.update();
        }
    }
}

2️⃣【抽象观察者 Observer】为所有的具体观察者定义一个接口,在得到主题的通知时更新自己。它的每一个实现类都是具体观察者。

public interface Observer {
     //更新
     public void update();
}

3️⃣【具体主题 ConcreteSubject】将有关状态存入具体观察者对象,在具体主题内部状态改变时,给所有登记过的观察者发出通知。继承 Subject 类,在这里实现具体业务,在具体项目中,该类会有很多变种。

public class ConcreteSubject extends Subject {
    //具体业务
    public void doSomething() {
        //...
        super.notifyObserver();
    }
}

4️⃣【具体观察者 ConcreteObserver】实现抽象观察者 Observer 所要求的更新接口,以便使本身的状态与主题的状态相协同。

public class ConcreteObserver implements Observer {
    @Override
    public void update() {
        System.out.println("收到消息,进行处理");
    }
}

5️⃣【客户端 Client】首先创建一个主题,然后定义一个观察者,将该观察者添加到该主题的观察者数组中,进行测试。

public class Client {
    public static void main(String[] args) {
        //创建一个主题
        ConcreteSubject subject = new ConcreteSubject();
        //定义一个观察者
        Observer observer = new ConcreteObserver();
        //观察
        subject.addObserver(observer);
        //开始活动
        subject.doSomething();
    }
}

运行结果如下:

二、观察者模式的应用简例

假设上班时间有一部分同事在看股票,一部分同事在看 NBA,这时老板回来了,前台通知了部分同事,这些同事没被发现,而没被通知到的同事被抓现行,被老板亲自“通知”关闭网页,UML 图如下:

1️⃣主题 Subject通知的发布者

public interface Subject {
    //增加
    public void attach(Observer observer);
    //删除
    public void detach(Observer observer);
    //通知
    public void notifyObservers();
    //状态
    public void setAction(String action);
    public String getAction();
}

2️⃣观察者

public abstract class Observer {
    protected String name;
    protected Subject subject;
    public Observer(String name, Subject subject) {
        this.name = name;
        this.subject = subject;
    }
    public abstract void update();
}

3️⃣具体通知者
前台 Secretary 和老板 Boss 作为具体通知者,实现 Subject 接口。Secretary 类的代码如下:

public class Secretary implements Subject {
    //同事列表
    private List<Observer> observers = new LinkedList<>();
    private String action;
    //添加
    @Override
    public void attach(Observer observer) {
        observers.add(observer);
    }
    //删除
    @Override
    public void detach(Observer observer) {
        observers.remove(observer);
    }
    //通知
    @Override
    public void notifyObservers() {
        for(Observer observer : observers) {
            observer.update();
        }
    }
    //前台状态
    @Override
    public String getAction() {
        return action;
    }
    @Override
    public void setAction(String action) {
        this.action = action;
    }
}

4️⃣具体观察者
StockObserver 是看股票的同事,NBAObserver 是看 NBA 的同事,作为具体观察者,继承 Observer 类。StockObserver 类的代码如下:

public class StockObserver extends Observer {
    public StockObserver(String name, Subject subject) {
        super(name, subject);
    }
    @Override
    public void update() {
        System.out.println(subject.getAction() + "\n" + name + "关闭股票行情,继续工作");
    }
}

5️⃣Client:前台作为通知者,通知观察者。这里添加 adam 和 tom 到通知列表,并从通知列表中删除了 adam,测试没在通知列表中的对象不会收到通知。

public class Client {
    public static void main(String[] args) {
        //前台为通知者
        Secretary secretary = new Secretary();
        StockObserver observer = new StockObserver("adam", secretary);
        NBAObserver observer2 = new NBAObserver("tom", secretary);

        //前台通知
        secretary.attach(observer);
        secretary.attach(observer2);

        //adam没被前台通知到,所以被老板抓了个现行
        secretary.detach(observer);

        //老板回来了
        secretary.setAction("小心!Boss回来了!");
        //发通知
        secretary.notifyObservers();
    }
}

运行结果如下,只有 tom 接收到了通知:

6️⃣Client:老板作为通知者,通知观察者。这里将 tom 从老板的通知列表中移除,老板只通知到了 adam。

public class Client {

    public static void main(String[] args) {
        //老板为通知者
        Boss boss = new Boss();

        StockObserver observer = new StockObserver("adam", boss);
        NBAObserver observer2 = new NBAObserver("tom", boss);

        //老板通知
        boss.attach(observer);
        boss.attach(observer2);

        //tom没被老板通知到,所以不用挨骂
        boss.detach(observer2);

        //老板回来了
        boss.setAction("咳咳,我大Boss回来了!");
        //发通知
        boss.notifyObservers();
    }
}

运行结果如下,只有 adam 挨骂了:

三、观察者模式的特性

1️⃣优点

  1. 一个对象状态改变,所有的依赖对象都将得到通知。
  2. 使用面向对象技术。
  3. 观察者和被观察者是抽象耦合的
  4. 建立了一套触发机制

2️⃣缺点

  1. 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间
  2. 如果观察者和观察目标间有循环依赖,可能导致系统崩溃
  3. 没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的

3️⃣使用场景

  1. 关联行为场景
  2. 事件多级触发场景
  3. 跨系统的消息变换场景,如消息队列的处理机制。

4️⃣应用实例

  1. 手机丢了,委托别人给其他人发消息通知。
  2. 通知老师/老板来了。
  3. 拍卖,拍卖师观察最高标价,然后通知给其它竞价者竞价。
  4. 在一个目录下建立一个文件,会同时通知目录管理器增加目录,并通知磁盘减少空间,文件是被观察者,目录管理器和磁盘管理器是观察者。
  5. 猫叫了一声,吓着了老鼠,也惊到了主人,猫是被观察者,老鼠和人是观察者。

5️⃣注意事项

  1. 避免循环引用
  2. 如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。
  3. 当一个对象的改变需要同时改变其它对象,并且它不知道具体有多少对象有待改变的时候,应该考虑使用观察者模式。
  4. 将一个系统分割成一系列相互协作的类有一个很不好的副作用,就是需要维护相关对象间的一致性。为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便,而观察者模式所做的工作就是在解除耦合。
【愚公系列】二十三种设计模式(十九)-观察者模式(Observer Pattern) 设计模式(Design Pattern)是软件开发领域的宝贵经验,是多人反复借鉴和广泛应用的代码设计指导。它们是一系列经过分类和归纳的代码组织方法,旨在实现可重用性、可维护性和可理解性。使用设计模式,我们能够编写高质量的代码,使其更易于他人理解,并提供了代码可靠性的保证。毫无疑问,设计模式对个人、团队和整个系统都带来了显著的益处。它们将代码开发提升到工程化水平,为软件工程构建提供了坚实的基础,就如同大厦的一块块精巧的砖石一样。在项目中明智地应用设计模式可以完美地解决各种复杂问题。 阅读详情

相关推荐

工业以太网通讯Profinet协议详解

Profinet是通过西门子控制系统被广泛使用的工业通信协议,是一种较新的,基于以太网的工业通讯协议。

mydatai的专栏 8852

设计模式第5讲——观察者模式(Observer)

观察者模式属于行为型模式。一、什么是观察者模式 二、特点 三、组成 四、应用场景4.1 生活场景4.2 程序场景 五、观察者模式实现5.0 UML类图5.1 Newspaper5.2 NewspaperImpl5.3 Subscriber5.4 SubscriberImpl5.5 测试

让~学习~成为一种习惯(橡 皮 人の技术博客) 2万+

RuoYi项目适配达梦数据库(二)

RuoYi项目,代码生成模块的达梦数据库适配。

邢慧鹏的博客 1万+

设计模式-观察者模式(Observer)

观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。观察者模式包含以下角色:主题(Subject):被观察的对象,维护一个观察者列表,提供添加、删除和通知观察者的方法。观察者(Observer):观察主题对象的状态变化,实现 Update 方法来更新自己的状态。

miaoyl的博客 7671

从零到一:ArduPilot无人船PID调参实战指南

本文详细介绍了ArduPilot无人船PID调参的实战指南,从基础参数设定到高级调参技术,帮助用户掌握水面环境下的PID控制逻辑。通过案例分析和参数示例,解决无人船在空载、负载变化及不同水域环境中的航行问题,提升无人船的稳定性和精确度。

weixin_29266647的博客 507

水文地质人必备:用Origin Pro 2023手把手教你搞定Piper三线图(附数据模板)

本文详细介绍了如何使用Origin Pro 2023绘制专业级Piper三线图,适用于水文地质数据分析。从数据准备、百分比计算到图表参数设置,提供全流程指导,并附赠数据模板和样式预设文件,帮助用户快速掌握这一水文地球化学分析的核心工具。

weixin_30568591的博客 533

设计模式之观察者模式详解

观察者模式 (Observer Pattern) 又叫发布-订阅模式 (Publish/Subscribe),定义一种一对多的依赖关系,一个主题对象 (被观察对象) 可被多个观察者对象同时监听,使得每当主题对象状态变化时,所有依赖于它的对象都会得到通知并被更新,属于行为型模式。 ​ 观察者模式的核心是将观察者与主题对象解耦,以类似于消息、广播发送的机制联动两者,使被观察者的变动能通知到感兴趣的观察者们,从而做出相应的响应

weixin_45538589的博客 6109

AUTOSAR从入门到精通-【应用篇】基于AUTOSAR架构的混合动力电池 ECU 软件开发

由于严峻的环境污染和能源短缺问题,各国都在致力于发展新能源车,以达到节能排放的目的。在此背景下,12V启停系统由于成本较低廉、匹配方便,得到广泛应用。但是12V系统作为启停系统后存在许多问题,比如节能和减排效果有限,并且轻度混合动力系统的功率需求通常在10~15KW,在此电压条件下运行时,电池的电流会达到1000A,因此该方案行不通。高压混合动力系统(>110V)的节油效果好,但是成本很高,并且需要大功率的电机。48V混合动力系统比高压混合动力系统成本。

getusushu的博客 1488

java设计模式-观察者模式

观察者模式介绍: 观察者模式(有时又被称为发布/订阅模式)是软件设计模式的一种。在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实时事件处理系统。 简单案例: 假设猫是老鼠和狗的观察目标,老鼠和狗是观察者,猫叫老鼠跑,狗也跟着叫,使用观察者模式描述该过程 抽象目标类 MySubject MySubject是抽象目标类,在其中定义了一个ArrayList类型的集合observers,用于存储观察者对象,并

张钰杰杰杰杰杰的博客 2233

【HAL库】STM32CubeMX开发----STM32F407----ETH+LWIP----TCPclient客户端

STM32F407开发板 为TCPclient客户端,PC端 为TCPserver服务端,相互之间的发送和接收实验。

MQ0522的博客 3048

torch.nn.rnn实现循环神经网络

------------------------------------nn.rnn模型实现。#------------------------------------模型实现。#-----------------------------------训练模型。#-----------------------------------训练模型。#--------------------------------读取数据。实现循环神经网络,并在至少一个数据集上进行实验,从训练时间、预测精度、...

matlab_python22的博客 2971

观察者模式(Observer Pattern)案例解析

观察者模式(Observer Pattern)案例解析 案例描述: 有一个雷达负责扫描目标,一旦发现目标,就会通知攻击序列对目标进行摧毁,攻击序列中的所有武器会向目标发动攻击。 现有的武器可以加入攻击序列,也可以退出攻击序列。 雷达扮演Subject,大炮和导弹扮演Observer,大炮和导弹通过attach加入到雷达的攻击序列,一旦雷达发现目标,启动攻击序列摧毁目标。

1161

YOLOv11 改进入门篇 | 轻量级涨点技巧:GhostConv 替代普通卷积的实战指南

摘要: 本文介绍如何通过GhostConv改进YOLOv11,实现轻量化涨点。YOLOv11深度增加导致参数量、延迟和内存占用上升,GhostConv通过“本征特征+线性变换”策略,在精度几乎无损的情况下降低30%-50%计算量。文章详细解析GhostConv原理,对比普通卷积的参数量和FLOPs优势,并提供完整的代码级改造流程,包括模块实现、注册及网络配置。实验表明,该方法有效提升边缘端推理效率,适用于移动端等资源受限场景。

shrgegrb的博客 1655

观察者模式-Observer Pattern

目录 模式的定义与特点 模式的结构与实现 模式的应用实例 模式的应用场景 模式的扩展 观察者模式是使用频率最高的设计模式之一,它用于建立一种对象与对象之间的依赖关系, 一个对象发生改变时将自动通知其他对象,其他对象将相应作出反应。在观察者模式中,发 生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察 者,而且这些观察者之间可以没有任何相互联系,可以根...

心猿意碼 4735

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

设计模式-17观察者模式Observer Pattern

观察者模式是一种行为型设计模式,用于在对象间建立一对多的依赖关系。当主题对象状态改变时,所有依赖的观察者对象会自动收到通知并更新。该模式适用于事件处理、发布-订阅机制等场景,能实现松耦合的系统架构。典型结构包括Subject接口(定义添加/删除观察者方法)、Observer接口(定义更新方法)以及具体实现类。实现时,主题对象维护观察者列表,状态变化时遍历列表通知所有观察者。这种模式广泛应用于GUI事件处理、消息推送系统等需要实时数据更新的场景。

d3y1`5 81_09 957

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Java - 【设计模式】观察者模式(Observer Pattern)

设计模式 - 观察者模式(Observer Pattern) -> 解决问题:一个对象的状态发生改变,如何通知其他对象? 被观察对象(Subject) 观察对象(Observer) -> 注意: 互相指定,互相包含! 一:被观察对象(Subject) 1> 维护一个可变对象,该对象变化对应一个方法,该方法内部需要通知所有观察者(notifyAllObservers) private int state; public void setState(int state) {

⚡ 579

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

观察者模式(Observer Pattern)详解

观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象状态发生变化时,它的所有依赖者(观察者)都会收到通知并自动更新。观察者模式又被称为发布-订阅(Publish/Subscribe)模式、模型-视图(Model-View)模式或源-监听器(Source-Listener)模式。观察者模式是一种强大且被广泛使用的设计模式,它允许对象之间进行松耦合的交互。通过将对象的依赖关系转换为松散耦合的观察者-主题关系,系统变得更加灵活和可维护。

yk_dflkg的博客 1939

观察者模式Observer Pattern

观察者模式定义了对象之间的一对多依赖,让多个观察者对象同时监听一个主体,当主体对象发生变化时,它的所有观察者都会收到通知。观察者模式也叫发布订阅模式,主要用于在关联行为之间建立一套触发机制的场景。 下面通过我们平时最常用的键盘鼠标相关的监听事件作为例子,来熟悉观察者模式。 一、首先创建Event类 public class Event { // 事件源,事件是由谁发起的,保存起来 ...

qq_37254296的博客 291

设计模式:观察者模式(Observer Pattern)

import java.util.ArrayList; import java.util.List; /** * 观察者模式。 * @author Bright Lee */ public class ObserverPattern { public static void main(String[] args) { Subject subject = new AnimalKe...

look4liming的专栏 311

设计模式-观察者模式(Observer Pattern)

本文结合代码详细地介绍了观察者模式的概念,适用场景,优缺点、实现方式,可以帮助读者更好地理解观察者模式

YUMIAloogy的博客~ 1268

Observer Pattern ——(观察者模式)

Observer Pattern 观察者模式定义 观察者模式是软件设计模式的一种。在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实时事件处理系统。 — 维基百科 观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。 在观察者模式中也有两个主

qq_38376634的博客 320

Design Pattern - Observer Pattern (设计模式 - 观察者模式)

什么是Observer Pattern?在一个系统中,有一个对象接收数据,其他若干对象监听来自这个对象数据的变化的这种情况可以使用design pattern,接受数据的这个对象我们称为 发送者 publisher; 监听变化的对象我么称为 观察者 observer。稍微具体的例子有一个天气的基站会接受来自三个不同感应器的数据,每当 weather 数据被改变时,weather obj就会更新 d...

YtdxYHZ的专栏 617

观察者模式——Observer Pattern

观察者模式-ObserverPattern最近在学习C#中的委托和事件,发现C#中事件响应依赖于委托实现,而记得java中的事件响应,则属于观察者模式!所以就像搞明白,委托和观察者模式的联系和区别!观察者模式:**当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时, 则会自动通知它的依赖对象。观察者模式属于行为型模式。** 介绍

kanbujian 496

设计模式:观察者模式(Observer Pattern、JDK实现)

import java.util.Observable; import java.util.Observer; /** * 观察者模式(JDK实现)。 * @author Bright Lee */ public class JdkObserverPattern { public static void main(String[] args) { AnimalKeeper su...

look4liming的专栏 333

Observer Pattern 观察者模式

Publisher, Subject Subscriber, Observer Observer Pattern: defines a one-to-many dependency between objects so that when one object changes state, all of its dependents are notified and updated a

Geurney的专栏 722

观察者模式(Observer Pattern)

观察者模式 当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。 案例一 天气预报需求 气象站可以将每天测量到的温度,湿度,气压等等以公告的形式发布出去(比如发布到自己的网站或第三方) 需要设计开放型API,便于其他第三方也能接入气象站获取数据 提供温度、气压和湿度的接口 测量数据更新时, 要能实时的通知给第三方 /** * 核心类 * 1. 包含最新的天气情况信息 * 2. 含有 Cur

jsxllht的博客 221
上一篇: Future 模式
下一篇: 不知道长度的 LinkedList,如何找到中间元素
JFS_Study
博客等级 码龄6年 363粉丝 359原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JFS_Study

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值