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

观察者模式的理解和实践

引言

        在软件开发中,设计模式是开发者们为了解决常见的设计问题而总结出来的一系列最佳实践。观察者模式(Observer Pattern)是其中一种非常经典且使用率极高的设计模式。它主要用于定义对象之间的一对多关系,使得当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。观察者模式广泛应用于GUI系统、订阅发布系统等场景,因为它能够有效实现解耦,降低对象之间的依赖性,使系统更加灵活和可扩展。

一、观察者模式的概念

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

        观察者模式的核心要素包括:

  1. 主题(Subject):也称为被观察者,它维护一个观察者列表,并在状态发生变化时通知所有观察者。
  2. 观察者(Observer):它定义一个更新接口,用于接收主题通知的变化。
  3. 具体主题(Concrete Subject):实现主题接口,维护观察者列表并通知它们状态的变化。
  4. 具体观察者(Concrete Observer):实现观察者接口,接收主题的通知并进行相应的更新。

二、观察者模式的优点和适用场景

优点

  1. 解耦:观察者模式将被观察者和观察者解耦,使得它们之间的依赖性更小,甚至做到毫无依赖。这大大提高了系统的灵活性和可扩展性。
  2. 动态更新:观察者模式支持动态添加和删除观察者,这使得系统能够在运行时根据需要动态调整观察者的数量。
  3. 广播通信:当一个对象的状态发生变化时,它会自动通知所有依赖的对象,这种广播通信机制非常适合用于事件驱动编程。

适用场景

  1. GUI系统:在图形用户界面(GUI)编程中,按钮、文本框等控件的事件处理通常使用观察者模式。控件作为被观察者,当用户进行操作时,会通知观察者(即事件处理器或监听器)来处理相应的事件。
  2. 订阅发布系统:观察者模式是发布-订阅系统的基础。在这种系统中,发布者发布消息,订阅者订阅感兴趣的消息类型。当某个消息类型被发布时,订阅者会收到通知并执行相应的处理逻辑。
  3. 数据模型与视图同步:在模型-视图-控制器(MVC)架构中,观察者模式通常用于数据模型和视图之间的更新同步。当模型中的数据发生变化时,所有依赖该模型的视图都会自动更新显示。
  4. 股票市场监测:在金融系统中,股票价格可能频繁变动,多个不同的系统(如显示价格的终端、交易系统等)都依赖这些变化。观察者模式可以让股票价格的变化自动通知所有依赖该数据的系统。

三、Java实现观察者模式

        下面我们通过Java代码来演示如何实现观察者模式。

1. 定义被观察者接口(Subject)

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


2. 定义观察者接口(Observer)

public interface Observer {
    void update(String message);
}


3. 实现具体主题(Concrete Subject)

import java.util.ArrayList;
import java.util.List;

public class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private String state;

    @Override
    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(state);
        }
    }

    public void setState(String state) {
        this.state = state;
        notifyObservers();
    }

    public String getState() {
        return state;
    }
}


4. 实现具体观察者(Concrete Observer)

public class ConcreteObserver implements Observer {
    private String name;

    public ConcreteObserver(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {
        System.out.println(name + " received message: " + message);
    }
}


5. 演示代码

public class ObserverPatternDemo {
    public static void main(String[] args) {
        // 创建主题对象
        ConcreteSubject subject = new ConcreteSubject();

        // 创建观察者对象
        ConcreteObserver observer1 = new ConcreteObserver("Observer 1");
        ConcreteObserver observer2 = new ConcreteObserver("Observer 2");

        // 注册观察者
        subject.addObserver(observer1);
        subject.addObserver(observer2);

        // 改变主题状态,通知观察者
        subject.setState("State 1");
        subject.setState("State 2");

        // 移除一个观察者
        subject.removeObserver(observer1);

        // 再次改变主题状态,只通知剩余的观察者
        subject.setState("State 3");
    }
}


运行结果

Observer 1 received message: State 1
Observer 2 received message: State 1
Observer 1 received message: State 2
Observer 2 received message: State 2
Observer 2 received message: State 3

四、观察者模式的实践

        在实际开发中,观察者模式的应用非常广泛。以下是一些具体的实践案例:

  1. GUI事件监听:在Java Swing或JavaFX等GUI框架中,按钮、文本框等控件的事件处理通常使用观察者模式。控件作为被观察者,当用户进行操作时,会通知观察者(即事件处理器或监听器)来处理相应的事件。

  2. 数据模型和视图同步:在MVC架构中,数据模型的变化需要实时同步到视图上。可以使用观察者模式,让数据模型作为被观察者,视图作为观察者。当数据模型发生变化时,会自动通知所有视图进行更新。

  3. 股票价格监控:在金融系统中,股票价格可能频繁变动。可以使用观察者模式,让股票价格作为被观察者,所有依赖股票价格的系统(如显示价格的终端、交易系统等)作为观察者。当股票价格发生变化时,会自动通知所有依赖的系统进行更新。

  4. 消息队列系统:在消息队列系统中,生产者将消息发送到队列中,消费者作为观察者订阅队列以接收和处理消息。可以使用观察者模式,让队列作为被观察者,消费者作为观察者。当有新消息到达队列时,会自动通知所有订阅的消费者进行处理。

总结

        观察者模式是一种非常经典且实用的设计模式,它定义了一种一对多的依赖关系,使得当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。观察者模式在GUI系统、订阅发布系统、数据模型与视图同步等场景中有着广泛的应用。通过Java代码实现观察者模式,我们可以更加深入地理解这一设计模式的原理和应用方法。希望本文能够帮助读者更好地掌握观察者模式,并在实际开发中灵活运用这一设计模式来解决问题。


http://www.kler.cn/a/430268.html

相关文章:

  • VSCode Live Server 插件安装和使用
  • Visio 画阀门 符号 : 电动阀的画法
  • 《繁星路》V1.8.3(Build16632266)官方中文学习版
  • 3D机器视觉的类型、应用和未来趋势
  • 流媒体内网穿透/组网/网络映射EasyNTS上云网关启动失败如何解决?
  • 28、使用StreamPark管理作业中,关于默认环境变量设置和默认动态参数设置的修改
  • vue的指令
  • Python 网络爬虫进阶:突破数据采集的边界
  • 【金猿CIO展】海博科技总经理兼CIO韩东明:大数据与大模型,驱动智能运维的新引擎...
  • 在Excel中实现选中单元格行列变色的功能
  • 基于SpringBoot实现验证码功能
  • C# WinForm —— 39 40 41 42 DataGridView 介绍与使用
  • k8s 之 Deployment
  • vue vxe-table 实现财务记账凭证并打印
  • Unix、GNU、BSD 风格中 ps 参数的区别
  • git将一个项目的文件放到另一个项目的文件夹下
  • 适配器模式 (Adapter) · 对象适配器 · 类适配器 · 实际开发中的应用
  • 游戏引擎学习第35天
  • 群控系统服务端开发模式-应用开发-邮件发送工具类
  • 【opencv入门教程】3. Rect 类用法
  • 嵌入式学习(15)-stm32通用GPIO模拟串口发送数据
  • 设计模式-装饰器模式(结构型)与责任链模式(行为型)对比,以及链式设计
  • 大舍传媒-关于海外媒体宣发的探讨
  • 【ONE·基础算法 || 动态规划(四)】
  • Hadoop不同版本的区别
  • apt 包 源 的维护 和缓存 命令