跟着GPT学设计模式之观察者模式

极客破浪者
• 阅读 157

你好,这里是codetrend专栏“跟着GPT学设计模式”。

引言

观察者模式(Observer Pattern)是一种行为型设计模式,它定义了对象之间的一对多依赖关系,使得当一个对象的状态发生改变时,其依赖对象都能够收到通知并自动更新。

观察者模式(Observer Design Pattern)也被称为发布订阅模式(Publish-Subscribe Design Pattern)。一般情况下,被依赖的对象叫作被观察者(Observable),依赖的对象叫作观察者(Observer)。

不过,在实际的项目开发中,这两种对象的称呼是比较灵活的,有各种不同的叫法,比如:Subject-Observer、Publisher-Subscriber、Producer-Consumer、EventEmitter-EventListener、Dispatcher-Listener。

在观察者模式中,有两个主要角色:主题(Subject)和观察者(Observer)。主题是被观察的对象,它维护了一个观察者列表,并提供方法用于添加、删除和通知观察者。

观察者是监听主题的对象,它定义了一个更新的方法,在主题状态改变时被调用。

观察者模式的一般工作流程:

  • 主题对象维护一个观察者列表,并提供方法用于注册、注销和通知观察者。
  • 观察者对象实现一个更新方法,用于在主题状态改变时被调用。
  • 当主题的状态发生改变时,它会遍历观察者列表,调用每个观察者的更新方法。
  • 观察者根据接收到的通知进行相应的操作,以使自身状态与主题保持一致。

使用 Mermaid 语法类图展示观察者模式的示意图如下:

classDiagram
    class Subject {
        + attach(Observer observer)
        + detach(Observer observer)
        + notifyObservers()
        # observers: Observer[]
    }

    class Observer {
        + update()
    }

    class ConcreteSubject {
        - state
        + getState()
        + setState(state)
    }

    class ConcreteObserver {
        + update()
    }

    Subject <|-- ConcreteSubject
    Subject "1" --> "*" Observer
    Observer <|-- ConcreteObserver
    ConcreteSubject --> ConcreteObserver
  • Subject 是主题类,包含了添加、删除和通知观察者的方法。observers 是一个观察者列表,用于存储注册的观察者对象。
  • Observer 是观察者类,定义了一个 update() 方法,用于在主题状态改变时被调用。
  • ConcreteSubject 是具体主题类,继承自 Subject,它有一个额外的 state 属性,表示当前状态,并提供了获取和设置状态的方法。
  • ConcreteObserver 是具体观察者类,继承自 Observer,实现了 update() 方法,根据主题状态的改变来更新自身状态。

这个类图展示了观察者模式的关键组件及它们之间的关系。主题与观察者之间是一对多的关系,主题可以有多个观察者。

当主题状态改变时,它会通过通知方法 notifyObservers() 来遍历观察者列表,并依次调用每个观察者的 update() 方法,从而实现观察者的更新操作。

观察者模式的使用场景

观察者模式在实际应用中有很多场景,以下是一些观察者模式的应用场景的举例:

  • GUI 事件处理:在图形用户界面(GUI)中,观察者模式被广泛应用于事件处理机制。当用户执行某个操作时,比如点击按钮或输入文本,这些操作会触发相应的事件。事件作为主题被通知给注册的观察者,观察者可以根据事件类型做出相应的响应,例如更新界面、执行特定逻辑等。
  • 订阅/发布模式:观察者模式也常被称为订阅/发布模式。在发布者-订阅者系统中,发布者充当主题的角色,订阅者则扮演观察者的角色。发布者负责发布消息,订阅者订阅感兴趣的消息类型,并在消息到达时执行相应的操作。这种模式广泛应用于消息队列系统、事件总线等。
  • 消息通知系统:观察者模式也可以用于构建消息通知系统。例如,一个新闻平台可以作为主题,用户可以选择订阅感兴趣的新闻类别作为观察者。当新闻发布时,平台会通知所有订阅了该类别的用户,并将新闻推送给他们。
  • 游戏开发中的事件管理:在游戏开发中,观察者模式常被用于事件管理。例如,游戏角色之间的互动和协作可以通过观察者模式实现。一个角色可以作为主题,其他角色可以注册为观察者。当主题(例如敌人角色)发生改变时,通知所有观察者(例如友方角色)并执行相应的行为。

实际上观察者模式非常灵活,适用于很多具有发布-订阅关系的场景。它提供了一种松耦合的设计方式,使得主题和观察者能够独立变化,并保持一致性。

观察者模式使用注意事项

  • 角色和职责:观察者模式中包括主题(Subject)和观察者(Observer)两个核心角色。主题负责管理观察者的注册、注销以及通知操作,而观察者则定义了接收更新通知并执行相应操作的方法。了解每个角色的职责和关系对于正确使用观察者模式非常重要。
  • 主题状态管理:主题在观察者模式中起到承载和管理状态的作用。当主题状态发生变化时,需要通知所有观察者。因此,需要合理设计和管理主题的状态,并及时触发通知操作。
  • 多线程安全性:在多线程环境下使用观察者模式时,需要考虑线程安全性。例如,在主题状态变化时,可能会遇到多个线程同时修改主题状态或触发通知的情况。需要采取相应的同步措施或使用线程安全的容器来确保并发访问的正确性。
  • 事件传递方式:观察者模式中,主题向观察者传递更新通知的方式可以是同步或异步的。在同步方式下,主题在通知观察者后会等待观察者执行完相应操作,才会继续执行;而在异步方式下,主题通知观察者后立即继续执行,观察者的更新操作在后台进行。了解不同的事件传递方式对系统行为和性能的影响是重要的。

观察者模式编程示例

下面通过一段代码来说明观察者模式的实现。

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

// 主题接口
interface Subject {
    void attach(Observer observer);
    void detach(Observer observer);
    void notifyObservers();
}

// 观察者接口
interface Observer {
    void update();
}

// 具体主题类
class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();

    @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();
        }
    }

    // 具体主题类的其他方法
    // ...
}

// 具体观察者类
class ConcreteObserver implements Observer {
    @Override
    public void update() {
        System.out.println("观察者收到更新通知,执行相应操作。");
    }
}

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

        // 创建具体观察者对象
        ConcreteObserver observer1 = new ConcreteObserver();
        ConcreteObserver observer2 = new ConcreteObserver();

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

        // 主题发生改变时,通知观察者
        subject.notifyObservers();
    }
}

在上述示例中定义了一个 Subject 接口和一个 Observer 接口,分别表示主题和观察者。

ConcreteSubject 是具体的主题类,实现了 Subject 接口,并包含了维护观察者列表、添加/删除观察者以及通知观察者的方法。

ConcreteObserver 是具体的观察者类,实现了 Observer 接口,并在 update() 方法中定义了观察者接收到更新通知时的操作。

在 main() 方法中创建了具体的主题对象 ConcreteSubject,以及两个具体的观察者对象 observer1 和 observer2。

然后通过 attach() 方法将观察者注册到主题中,然后调用 notifyObservers() 方法通知所有的观察者。当主题发生改变时,所有观察者都会收到更新通知,并执行相应的操作。

以上内容基于 GPT 创建和整理。

关于作者

来自一线全栈程序员nine的探索与实践,持续迭代中。

欢迎关注或者点个赞~

点赞
收藏
评论区
推荐文章
观察者模式在spring中的应用
作者:王子源1观察者模式简介1.1定义指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布订阅模式、模型视图模式,它是对象行为型模式。
happlyfox happlyfox
4年前
笑说设计模式-小白逃课被点名
关于我简介工厂模式(FactoryPattern)是最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,而是通过使用一个共同的接口来指向新创建的对象。分类工厂模式可以分为三种,其中简单工厂一般不被认为是一种设计模式,可以将其看成是工厂方法的一种特殊
Wesley13 Wesley13
3年前
java设计模式详细讲解
原文链接:java设计模式详细讲解观察者模式(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.blogchina.cn%2Fblog%2Fguopengfei%2Fhome%2F270%2F1575725711626"java设计模式详细讲解观察者模式")如果想要更加
Wesley13 Wesley13
3年前
java中的23种设计模式
java中一共23种设计模式!按照目的来分,设计模式可以分为创建型模式、结构型模式和行为型模式。创建型模式用来处理对象的创建过程;结构型模式用来处理类或者对象的组合;行为型模式用来对类或对象怎样交互和怎样分配职责进行描述。创建型模式用来处理对象的创建过程,主要包含以下5种设计模式:工厂方法模
尼克 尼克
4年前
简说设计模式——观察者模式
一、什么是观察者模式  观察者一般可以看做是第三者,比如在学校上自习的时候,大家肯定都有过交头接耳、各种玩耍的经历,这时总会有一个“放风”的小伙伴,当老师即将出现时及时“通知”大家老师来了。再比如,拍卖会的时候,大家相互叫价,拍卖师会观察最高标价,然后通知给其它竞价者竞价,这就是一个观察者模式。  对于观察者模式而言,肯定有观察
Wesley13 Wesley13
3年前
Java设计模式
一、策略模式(让算法与对象独立)    策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。!(http://static.oschina.net/uploads/space/2016/1108/180244_oYm8_1789589.png)二、观察者模式(让你的对象知悉现状) 
Wesley13 Wesley13
3年前
Java Design Patterns
java的设计模式大体上分为三大类:创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组合模式,享元模式。行为型模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模
Wesley13 Wesley13
3年前
PHP状态模式
状态设计模式状态模式的作用是允许对象在状态改变时改变其行为对象中频繁的状态非常依赖于条件语句,就自身来说条件语句并没有什么问题,不过,如果选项太多,以至于程序出现混乱,或者增加或改变选项需要太多的是时间。<?php/CreatedbyPhpStorm.User:ge
Wesley13 Wesley13
3年前
PHP观察者模式
其实不用刻意去学习模式,我们平常看代码,写代码的过程中已经接触或使用过不少设计模式,只是我们不知道罢了。但是我们仍然需要了解一下书上的说法,对比印证一下,加深理解。本文说的是设计模式:观察者模式根据字面意思理解,我们知道关键字是“观察”两个字,这是一个动词,那么就需要有"被观察者"和"观察者"。举个栗子:公司有一台很重要的线上服务器,以及一个
Wesley13 Wesley13
3年前
00_设计模式之语言选择
设计模式之语言选择设计模式简介背景设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。设计模式(Designpattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的
设计模式-单例模式概述 | 京东云技术团队
我们常把23种经典的设计模式分为三类:创建型、结构型、行为型,其中创建型设计模式主要解决“对象的创建”问题,将创建和使用代码解耦,结构型设计模式主要解决“类或对象的组合或组装”问题,将不同功能代码解耦,行为型设计模式主要解决“类或对象之间的交互”问题,将不