首页 > 其他分享 >什么是观察者设计模式?

什么是观察者设计模式?

时间:2024-04-17 16:37:14浏览次数:22  
标签:Observer Spring 什么 观察者 事件 news 设计模式 void

什么是观察者

观察者模式的主要角色包括:

  • 主题(Subject): 也称为被观察者或可观察对象。它维护了一系列观察者对象,并提供方法用于注册、删除和通知观察者。当主题的状态发生改变时,它会通知所有注册的观察者。

  • 观察者(Observer): 观察主题的对象。观察者定义了一个更新方法,主题在状态改变时会调用这个方法来通知观察者。观察者可以根据主题的通知来执行相应的操作。

观察者的应用

观察者模式在实际应用中经常用于处理事件驱动的编程场景,如图形用户界面(GUI)开发、消息传递系统等。通过观察者模式,可以实现对象之间的解耦,提高系统的灵活性和可维护性。
Spring Framework中,观察者模式的应用非常广泛,尤其在Spring的事件驱动机制中。Spring的事件机制允许对象在特定事件发生时发布事件,并允许其他对象注册为监听器以接收这些事件。这与观察者模式的概念非常相似,其中事件源就是观察者模式中的主题,而事件监听器就是观察者。

应用程序事件: Spring允许应用程序发布自定义事件,并提供了ApplicationEvent和ApplicationListener接口。应用程序可以创建自定义事件类,并在需要时发布这些事件。其他对象可以实现ApplicationListener接口并注册为监听器,以接收并处理这些事件。

Spring MVC事件: 在Spring MVC中,可以使用 ApplicationEventPublisher 接口发布自定义事件,并通过@EventListener注解或实现 ApplicationListener 接口的方式来处理这些事件。这使得在MVC架构中进行解耦和处理事件变得更加容易。

如何实现

日常中比较经典的实例场景 , 举个例子,如博客园的文章订阅, 当关注的作者发布了新的文章后,关注其的粉丝就会收到消息通知,这里将代码拆出来如下。

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

// 主题接口
interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers(String news);
}

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

// 新闻发布者
class NewsPublisher implements Subject {
    private List<Observer> observers = new ArrayList<>();

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

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

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

    public void publishNews(String news) {
        System.out.println("发布新闻: " + news);
        notifyObservers(news);
    }
}

// 观察者 - 读者
class Reader implements Observer {
    private String name;

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

    @Override
    public void update(String news) {
        System.out.println(name + " 收到新闻: " + news);
    }
}

public class ObserverPatternExample {
        // 创建新闻发布者
        NewsPublisher publisher = new NewsPublisher();

        // 创建两个观察者(读者)
        Observer reader1 = new Reader("小明");
        Observer reader2 = new Reader("小红");

        // 注册观察者
        publisher.registerObserver(reader1);
        publisher.registerObserver(reader2);

        // 发布新闻
        publisher.publishNews("Java 21发布了!");
        publisher.publishNews("Spring Framework 更新了!");

        // 读者取消订阅
        publisher.removeObserver(reader2);

        // 再次发布新闻
        publisher.publishNews("小米 su7 上线了,雷总为你开车门,快行动起来吧!");
    }
}

程序运行日志如下

发布新闻: Java 21发布了!
小明 收到新闻: Java 21发布了!
小红 收到新闻: Java 21发布了!
发布新闻: Spring Framework 更新了!
小明 收到新闻: Spring Framework 更新了!
小红 收到新闻: Spring Framework 更新了!
发布新闻: 小米 su7 上线了,雷总为你开车门,快行动起来吧!
小明 收到新闻: 小米 su7 上线了,雷总为你开车门,快行动起来吧!

结语

这里介绍观察者,是希望从易于理解的概念开始对 Reactive Programing 的理解,在响应式编程中多数基于观察者模式思想演变而来,如在 Reactor 中,订阅者(Subscriber)订阅了数据流(Publisher),并在数据流中的元素发生变化时接收通知。

通知机制: 在观察者模式中,主题状态的变化会触发通知,通知会被发送给所有注册的观察者。在Reactor中,数据流中的元素发生变化时会触发通知,通知会被发送给所有订阅了该数据流的订阅者。

事件驱动编程: 观察者模式和 Reactor 都支持事件驱动的编程模型。在观察者模式中,事件源(主题)发生事件(状态变化),并通知观察者。在 Reactor 中,事件(数据元素)在流中传递,并且订阅者可以对这些事件进行响应式地处理。

标签:Observer,Spring,什么,观察者,事件,news,设计模式,void
From: https://www.cnblogs.com/pengpengon/p/18141025/Reactive_Programming_Design

相关文章

  • 工程化、模块化、组件化 开发工作中这三项有什么区别
    工程化:定义:工程化是一种遵循一定标准和规范,通过工具提高效率、降低成本的开发手段。它涉及整个开发流程的规划和管理,确保项目能够按照预定的目标和质量要求完成。关注点:工程化关注于整体的开发流程、项目结构、工具链的整合以及团队协作等方面。它强调使用工具和自动化手段来优......
  • 网络审计:为什么定期检查您的网络很重要
    本文分享自天翼云开发者社区《网络审计:为什么定期检查您的网络很重要》,作者:易乾在数字化时代,网络安全成为组织和个人必须面对的重要挑战。网络审计是一种关键的安全措施,通过定期检查和评估网络系统的安全性,帮助发现潜在的安全漏洞和弱点,从而防止数据泄露和其他安全威胁。本文将介......
  • c# 什么是逻辑非?
    什么是逻辑非?术语“逻辑非”是指一元求反运算符 !。有些人称该运算符之为“非运算符”。将 ! 运算符置于条件表达式(或计算结果为 true 或 false 的任何代码)之前时,它会强制代码反转其对操作数的求值。应用逻辑非时,如果操作数的计算结果为 false,则计算结果为 true;如果......
  • 正六面体教会我们什么 | 解题经验
    前言正六面体,也就是正方体,是我们从小学和初中就学习的数学素材,高中阶段的深入学习中也多次研究这个重要素材。编辑中。。。经验总结➊依托正方体研究、理解棱柱、棱锥、棱台的结构特征;➋正方体中的正四面体,补体;➌正方体中的内切球、棱切球、外接球;➍确定基向量,来表示空间中......
  • 我们为什么需要进程?
    我们为什么需要进程(Process)?首先,什么是进程?进程,在非正式定义上是指运行中的程序或进行中的程序,是操作系统对程序的抽象。进程不只是程序,它是外存程序在内存的副本,一个程序可以有多个进程。好,所以我们为什么需要进程(Process)来作为程序的抽象?      因为在实际使用中,人们......
  • void swap(double& val1,double& val2); 这是什么意思
    voidswap(double&val1,double&val2);这是什么意思?定义了一个叫做swap的函数,它接受两个双精度数的引用作为参数在C++中,&符号用于表示引用。通过传递引用作为参数,函数可以直接修改传递给它的参数的值,而不是创建参数的副本。通过传递引用而不是传递参数的副本,可以避免不必......
  • 为什么钱难赚? 因为你想的到和想不到的方向, 都有人在做了
    赚钱的种类大家都知道,赚钱无非三种钱滚钱资源、背景换钱体力、脑力换钱对于前两种,没啥好说的,投胎是门技术活.绝大部分人,包括我在内都是第三种.而对于这一类人来说,赚钱是非常难的.这里说的赚钱不是一个月赚个吃饭钱,而是通过行动达到远超打工的收益.大家都......
  • python 有什么资格称为编程排行榜第一
    python有什么资格称为编程排行榜第一?你确定没开玩笑吗?python的开发者以及使用者从来就没有说过python为编程排行榜第一,语言永远都只是一个工具,杀鸡用菜刀,砍树用斧头,那你能说斧头一定比菜到好使吗?编程排行榜是基于某些指标进行评估的,不同的指标可能会导致不同的排名结果。所以讨......
  • 为什么说降维是超越聚类的无监督学习
    降维通常被视为超越聚类的无监督学习技术,因为它不仅仅是将数据分组。降维的目标是发现数据中的底层结构,通过减少数据的维数来简化数据,同时尽可能保留重要的信息。这使得降维成为一种更为基础和广泛的数据探索方法。以下是降维超越聚类的几个方面:数据压缩:降维可以减少数据集的大......
  • 为什么python的数据库语句要用参数化构造的方式
    以下是一个python的数据库插入语句self.cur.execute('''INSERTINTObooks(url,title,product_type,price_excl_tax,price_incl_tax,availability,num_reviews,rating,category,describe)VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)&......