设计模式之观察者模式

一、观察者模式介绍

观察者模式(Observer Pattern)是一种行为设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

1、观察者模式的结构

观察者模式类图结构:

观察者模式主要涉及以下角色:

  1. Subject(主题):它把所有对观察者对象的引用保存在一个聚集(比如ArrayList对象)里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,主题的状态发生变化时会通知所有的观察者对象。

  2. Observer(观察者):为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫做更新接口。

  3. ConcreteSubject(具体主题):将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。

  4. ConcreteObserver(具体观察者):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。如果需要,具体观察者角色可以保持一个指向具体主题对象的引用。

2、观察者模式的应用场景

  • 当一个对象的改变需要同时改变其他对象,而且它不知道具体有多少对象有待改变时。
  • 当一个对象必须通知其他对象,而它又不能假定其他对象是谁。换言之,你不希望这些对象是紧密耦合的。

3、观察者模式的优点

  1. 观察者模式可以实现表示层和数据逻辑层的分离,并定义了稳定的消息更新传递机制,抽象了更新接口,使得可以有各种各样不同的表示层作为具体观察者角色。
  2. 观察者模式在观察目标和观察者之间建立一个抽象的耦合。
  3. 观察者模式支持广播通信。

4、观察者模式的缺点

  1. 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
  2. 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
  3. 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

观察者模式是一种非常有用的设计模式,在软件开发中有着广泛的应用,特别是在实现事件处理系统、数据监控系统等方面。

现在随着Kafka、RocketMq等消息中间件的应用,观察者的一些缺点也已经被弥补,但是其设计思想,在一个JVM应用内的场景,还是非常有用的。

二、观察者模式例子

下面是一个简单的Java观察者模式的例子,包括一个主题(Subject)和两个观察者(Observer1 和 Observer2)。当主题的状态发生变化时,所有注册的观察者都会收到通知并更新自己的状态。

import java.util.ArrayList;  
import java.util.List;  
  
// 观察者接口  
interface Observer {  
    void update(String message);  
}  
  
// 具体观察者1  
class Observer1 implements Observer {  
    public void update(String message) {  
        System.out.println("Observer1 received: " + message);  
    }  
}  
  
// 具体观察者2  
class Observer2 implements Observer {  
    public void update(String message) {  
        System.out.println("Observer2 received: " + message);  
    }  
}  
  
// 主题  
class Subject {  
    private List<Observer> observers = new ArrayList<>();  
    private String message;  
  
    public void attach(Observer observer) {  
        observers.add(observer);  
    }  
  
    public void detach(Observer observer) {  
        observers.remove(observer);  
    }  
  
    public void notifyUpdate(String message) {  
        this.message = message;  
        for (Observer observer : observers) {  
            observer.update(message);  
        }  
    }  
}  
  
// 测试类  
public class ObserverPatternDemo {  
    public static void main(String[] args) {  
        Subject subject = new Subject();  
  
        Observer observer1 = new Observer1();  
        Observer observer2 = new Observer2();  
  
        subject.attach(observer1);  
        subject.attach(observer2);  
  
        subject.notifyUpdate("Hello Observers!");  
  
        subject.detach(observer1);  
  
        subject.notifyUpdate("Second message!");  
    }  
}

在这个例子中,Subject 类维护了一个观察者列表,并提供了 attach 和 detach 方法来添加和移除观察者。notifyUpdate 方法用于通知所有注册的观察者主题的状态已经改变。

Observer1 和 Observer2 类实现了 Observer 接口,该接口定义了一个 update 方法,用于接收主题状态变化的通知。

在 ObserverPatternDemo 测试类中,创建了一个 Subject 对象和两个观察者对象,并将这两个观察者注册到主题上。然后,通过调用 notifyUpdate 方法来改变主题的状态,并观察输出结果。最后,移除了一个观察者并再次发送通知,以演示观察者可以从主题中注销。

核心要点:subject主题负责维护好观察者列表,在发生事件时,通知所有的观察者,还是非常简单的一个模式。

如果觉得对你有用,记得点赞 加 关注。

相关推荐

  1. 【前端设计模式观察模式

    2024-07-12 17:16:05       54 阅读
  2. 设计模式观察模式

    2024-07-12 17:16:05       50 阅读
  3. 设计模式观察模式

    2024-07-12 17:16:05       53 阅读
  4. 设计模式观察模式

    2024-07-12 17:16:05       49 阅读
  5. go 设计模式观察模式

    2024-07-12 17:16:05       50 阅读
  6. 设计模式观察模式

    2024-07-12 17:16:05       49 阅读
  7. C++ 设计模式观察模式

    2024-07-12 17:16:05       47 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-12 17:16:05       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-12 17:16:05       71 阅读
  3. 在Django里面运行非项目文件

    2024-07-12 17:16:05       58 阅读
  4. Python语言-面向对象

    2024-07-12 17:16:05       69 阅读

热门阅读

  1. 软设之享元模式

    2024-07-12 17:16:05       20 阅读
  2. 3179. K 秒后第 N 个元素的值

    2024-07-12 17:16:05       21 阅读
  3. mysql中的二进制数据类型

    2024-07-12 17:16:05       19 阅读
  4. mysql8遇到的报错Public Key Retrieval is not allowed

    2024-07-12 17:16:05       21 阅读
  5. MySQL事务

    2024-07-12 17:16:05       20 阅读
  6. C语言阶乘(只用逻辑运算中的短路效应判断)

    2024-07-12 17:16:05       20 阅读
  7. numpy 解释函数nanmax

    2024-07-12 17:16:05       22 阅读
  8. AIGC:AI创作短片-流程以及工具介绍(学习笔记)

    2024-07-12 17:16:05       23 阅读
  9. NLP简介

    NLP简介

    2024-07-12 17:16:05      20 阅读
  10. Linux 内核中的 Makefile 和 Kconfig:深入理解与实践

    2024-07-12 17:16:05       18 阅读
  11. 【Cesium开发实战】淹没分析功能的实现

    2024-07-12 17:16:05       19 阅读