【设计模式系列】——观察者模式攻坚战

简介: 【设计模式系列】——观察者模式攻坚战

概述


观察者模式,又叫发布/订阅模式(Publish-Subscribe)。定义对象之间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于他的对象都会收到通知并且执行对应的更新逻辑。

在日常生活中也有很多也有很多观察者模式的场景,比如我们订阅某个电视剧,当电视剧有更新的时候,我们会收到通知。这里观察者对象就是我们用户,被观察者对象就是电视剧。


程序案例


我们把上面电视剧的订阅通过代码实现一下。

1671115282647.jpg

  1. 定义观察者对象Observer

抽象出观察者对象,有很多不同类别的具体观察者对象,比如学生,上班族,家庭妇女等。

public interface TVObserver {
    /**
     * 处理
     * @param message 消息
     */
    void process(String message);
}

具体的学生观察者对象

public class StudentTvObserver implements TvObserver{
    @Override
    public void process(String message) {
        System.out.println("我是学生," + message + ", 我要翘课追剧了");
    }
}

具体的打工人观察者对象

public class WorkerTvObserver implements TvObserver {
    @Override
    public void process(String message) {
        System.out.println("我是打工人," + message + ", 我只能下班看了");
    }
}
  1. 定义被观察对象Subject

定义抽象的被观察对象或者主题,因为电视剧其实有很多,比如《梦华录》,《士兵突击》等,都需要单独订阅。

public abstract class Tv {
    private String tvName;
    private List<TvObserver> tvObservers = new ArrayList<>();
    //增加订阅者
    public void subscribe(TvObserver observer) {
        tvObservers.add(observer);
    };
    //取消订阅
    public void unsubscribe(TvObserver observer) {
        tvObservers.remove(observer);
    }
    //通知订阅者更新消息
    public void notify(String message) {
        tvObservers.forEach(item -> {
            item.process(message);
        });
    }
    public String getTvName() {
        return tvName;
    }
    public void setTvName(String tvName) {
        this.tvName = tvName;
    }
}

定义具体的被观察者的对象,也就是你要订阅的电视剧《梦华录》

public class MengHuaLuTv extends Tv {
    public MengHuaLuTv() {
        this.setTvName("梦华录");
    }
    @Override
    public void notify(String message) {
        System.out.println("梦华录大结局了,开始推送给大家");
        super.notify(message);
    }
}
  1. 执行测试
public class Test {
    public static void main(String[] args) {
        Tv tv = new MengHuaLuTv();
        TvObserver studentOb = new StudentTvObserver();
        tv.subscribe(studentOb);
        WorkerTvObserver workerTvObserver = new WorkerTvObserver();
        tv.subscribe(workerTvObserver);
        // 通知
        tv.notify("梦华录大结局啦");
    }
}

输出:

1671115305937.jpg


优缺点


优点


  1. 降低目标与观察者对象之间的耦合关系。
  2. 被观察者发送通知,所有注册的观察者收到通知,处理对应的逻辑,实现广播机制。


缺点


  1. 如果观察者对象很多的话,那么所有观察者收到通知的时间会很长
  2. 如果观察者对象的处理逻辑写的存在问题,会级联影响其他观察者对象收到通知的时间。


适用场景


  1. 对象间存在一对多关系,一个对象的状态发生改变会影响其他对象。
  2. 当多个对象存在依赖关系,但是你不想要他们之间耦合,可以考虑适用观察者模式。


更多案例


jdk中的观察者模式


在 Java 中,通过 java.util.Observable 类和 java.util.Observer 接口定义了观察者模式,只要实现它们的子类就可以编写观察者模式实例。

  1. Observer 接口

Observer 接口是抽象观察者,它监视目标对象的变化,当目标对象发生变化时,观察者得到通知,并调用 update 方法,进行相应的工作。

  1. Observable类

Observable 类是抽象目标类(被观察者),它有一个 Vector 集合成员变量,用于保存所有要通知的观察者对象,下面来介绍它最重要的 3 个方法。

  • void addObserver(Observer o) 方法:用于将新的观察者对象添加到集合中。
  • void notifyObservers(Object arg) 方法:调用集合中的所有观察者对象的 update方法,通知它们数据发生改变。通常越晚加入集合的观察者越先得到通知。
  • void setChange() 方法:用来设置一个 boolean 类型的内部标志,注明目标对象发生了变化。当它为true时,notifyObservers() 才会通知观察者。

实际上,我们可以把上面的电视剧订阅的例子可以直接用jdk中的接口实现。


Zookeeper中的Watch机制


Zookeeper中也有类似的观察者模式,就是Watch机制,zk客户端向服务端注册监听某个节点或者节点中的数据,如果节点的路径或者数据发生变化,便会收到来时zk服务端的通知,执行相应的处理逻辑。


Springboot的监听器


Springboot中的监听器机制,本质上也是观察者模式的衍生。

  1. 监听器(ApplicationListener)对应于观察者模式中的观察者。监听器监听特定事件,并在内部定义了事件发生后的响应逻辑。
  2. 事件发布器(ApplicationEventMulticaster)对应于观察者模式中的被观察者/主题, 负责通知观察者(监听器) 对外提供发布事件和增删事件监听器的接口,维护事件和事件监听器之间的映射关系,并在事件发生时负责通知相关监听器。
  3. 事件(ApplicationEvent)负责对应相应监听器 事件源发生某事件是特定事件监听器被触发的原因。
目录
相关文章
|
设计模式 监控 Java
Kotlin - 改良设计模式 - 观察者模式
Kotlin - 改良设计模式 - 观察者模式
309 3
|
12月前
|
设计模式 缓存 Java
Java设计模式(二):观察者模式与装饰器模式
本文深入讲解观察者模式与装饰器模式的核心概念及实现方式,涵盖从基础理论到实战应用的全面内容。观察者模式实现对象间松耦合通信,适用于事件通知机制;装饰器模式通过组合方式动态扩展对象功能,避免子类爆炸。文章通过Java示例展示两者在GUI、IO流、Web中间件等场景的应用,并提供常见陷阱与面试高频问题解析,助你写出灵活、可维护的代码。
|
10月前
|
设计模式 消息中间件 传感器
Java 设计模式之观察者模式:构建松耦合的事件响应系统
观察者模式是Java中常用的行为型设计模式,用于构建松耦合的事件响应系统。当一个对象状态改变时,所有依赖它的观察者将自动收到通知并更新。该模式通过抽象耦合实现发布-订阅机制,广泛应用于GUI事件处理、消息通知、数据监控等场景,具有良好的可扩展性和维护性。
676 8
|
设计模式 存储 供应链
前端必须掌握的设计模式——观察者模式
观察者模式(Observer Pattern)是一种行为型设计模式,实现了一种订阅机制。它包含两个角色:**观察者**(订阅消息、接收通知并执行操作)和**被观察者**(维护观察者列表、发送通知)。两者通过一对多的关系实现解耦,当被观察者状态改变时,会通知所有订阅的观察者。例如,商店老板作为被观察者,记录客户的需求并在商品到货时通知他们。前端应用中,如DOM事件注册、MutationObserver等也体现了这一模式。
|
设计模式 监控 Java
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
|
设计模式 传感器
【设计模式】观察者模式(定义 | 特点 | Demo入门讲解)
【设计模式】观察者模式(定义 | 特点 | Demo入门讲解)
319 0
|
设计模式 消息中间件 存储
【设计模式】【行为型模式】观察者模式(Observer)
一、入门 什么是观察者模式? 观察者模式(Observer Pattern)是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会收到通知并自动更新。
554 9
|
设计模式 消息中间件 存储
设计模式:观察者模式
观察者模式属于行为型设计模式,用于建立对象间的一对多依赖关系。当主题(Subject)状态变化时,所有依赖的观察者(Observer)会自动收到通知并更新。
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
379 6