Spring Event 观察者模式, 业务解耦神器

这篇具有很好参考价值的文章主要介绍了Spring Event 观察者模式, 业务解耦神器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Spring Event 观察者模式, 业务解耦神器

Spring Event 观察者模式, 业务解耦神器

观察者模式在实际开发过程中是非常常见的一种设计模式。

Spring Event的原理就是观察者模式,只不过有Spring的加持,让我们更加方便的使用这一设计模式。

一、什么是观察者模式

概念: 观察者模式又叫发布-订阅模式。

发布指的是当目标对象的状态改变时,它就向它所有的观察者对象发布状态更改的消息,以让这些观察者对象知晓。

举例:

网上有一个非常符合观察者模式的例子

Spring Event 观察者模式, 业务解耦神器

当温度有变化,对应的仪表盘也会跟着变化。

一个仪表盘可以当作一个观察者,去掉一个仪表盘或者新增一个仪表盘跟目标对象(温度)是解耦的,不是强绑定关系。

一句话:感知变化,相应变化


二、观察者模式 VS 责任链模式

这两种设计模式是有相似的地方,但其实有很大的区别。

我们先来看相似的点,就好比上面的这个例子,我们是不是也可以用责任链模式来实现?

当然可以了。

当温度变化了,一条一条链路的执行下去就是了。

Spring Event 观察者模式, 业务解耦神器

当然如果是我,这个功能在选择设计模式的时候,我还是会选择使用观察者模式。

1、区别

我个人认为主要有四点区别:

「第一点」:我们也会称观察者模式为发布订阅模式,作为订阅者来讲,每个订阅者是平级的,也就是每个观察者对象是平级的,但责任链可以有先后次序。

比如我们在电商场景中,有个电商活动,这个商品需要先走 包邮活动->满减送->会员折扣活动->积分抵扣活动。

这个责任链的顺序不同会导致最终优惠的价格不同。

「第二点」:所有观察者一般接收统一参数,但责任链获取的参数可能是上一个链路已经处理完成的

就好比上面的电商活动,会员折扣活动计算后的价格,还会传入到积分抵扣活动中。

「第三点」:观察者的对象都会执行,但责任链这我们可以在得到满意结果直接返回。

比如我想查一个份数据,这个数据可以先从A -> B -> C,三个接口获得。只要返回数据,这个链路就不用往下走了。

「第四点」:观察者模式可以做异步操作,我们说的MQ发布订阅模式,就是完全异步,但是责任链不太适合走异步。


三、代码示例

1、观察者模式有哪些角色

抽象被观察者: 定义了一个接口,包含了注册观察者、删除观察者、通知观察者等方法。

具体被观察者: 实现了抽象被观察者接口,维护了一个观察者列表,并在状态发生改变时通知所有注册的观察者。

抽象观察者: 定义了一个接口,包含了更新状态的方法。

具体观察者: 实现了抽象观察者接口,在被观察者状态发生改变时进行相应的处理。

  1. 抽象被观察者
/**
 * 抽象被观察者
 */
public interface ISubject {

    /**
     * 新增观察者
     */
    boolean attach(IObserver observer);

    /**
     * 删除观察者
     */
    boolean detach(IObserver observer);

    /**
     * 通知观察者
     */
    void notify(String event);
}
  1. 抽象观察者
/**
 *  抽象观察者
 */
public interface IObserver {
   
    /**
     * 观察者所执行方法
     */
    void update(String event);
}
  1. 具体被观察者
/**
 *  具体被观察者
 */
public class ConcreteSubject implements ISubject {

    private List<IObserver> observers = new ArrayList<>();

    @Override
    public boolean attach(IObserver observer) {
        return this.observers.add(observer);
    }

    @Override
    public boolean detach(IObserver observer) {
        return this.observers.remove(observer);
    }

    @Override
    public void notify(String event) {
        System.out.println("被观察者: 数据变更 = " + event);
        for (IObserver observer : this.observers) {
             observer.update(event);
        }
    }
}
  1. 具体观察者
/**
 * 具体观察者
 */
public class ConcreteObserver implements IObserver {

    @Override
    public void update(String event) {
        System.out.println("观察者: 收到被观察者的温度变动: " + event);
    }
}
  1. 测试
/**
 *  测试
 */
public class ClientTest {
    
    public static void main(String[] args) {
        // 被观察者
        ISubject subject = new ConcreteSubject();
        // 观察者
        IObserver observer = new ConcreteObserver();
        // 将观察者注册
        subject.attach(observer);
        // 被观察者通知观察者
        subject.notify("温度从6变到7");
    }
}

运行结果

被观察者: 数据变更 = 温度从6变到7
观察者: 收到被观察者的温度变动: 温度从6变到7

当然上面这种模式也太傻了吧,下面就通过Spring Event实现观察者模式,非常方便。


四、Spring Event 实现观察者模式

Spring 基于观察者模式实现了自身的事件机制,由三部分组成:

事件 ApplicationEvent: 通过继承它,实现自定义事件。

事件发布者 ApplicationEventPublisher: 通过它,可以进行事件的发布。

事件监听器 ApplicationListener: 通过实现它,进行指定类型的事件的监听。

这里以下面案例实现,当一个用户出现欠费,那么通过观察者模式通过 短信通知,邮箱通知,微信通知,到具体用户

Spring Event 观察者模式, 业务解耦神器

1、事件 UserArrearsEvent

继承 ApplicationEvent 类,用户欠费事件。

/**
 * 用户欠费事件 继承ApplicationEvent
 */
public class UserArrearsEvent extends ApplicationEvent {

    /**
     * 用户名
     */
    private String username;
    
    public UserArrearsEvent(Object source, String username) {
        super(source);
        this.username = username;
    }

    public String getUsername() {
        return username;
    }
}

2、被观察者 UserArrearsService

/**
 *  被观察者 实现ApplicationEventPublisherAware 接口
 */
@Service
public class UserArrearsService implements ApplicationEventPublisherAware {

    private Logger logger = LoggerFactory.getLogger(getClass());

    private ApplicationEventPublisher applicationEventPublisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    public void arrears(String username) {
        // 执行欠费逻辑
        logger.info("被观察者 用户欠费,用户名称", username);
        // 发布
        applicationEventPublisher.publishEvent(new UserArrearsEvent(this, username));
    }

}
  1. 实现 ApplicationEventPublisherAware 接口,从而将 ApplicationEventPublisher 注入到其中。

  2. 在执行完注册逻辑后,调用 ApplicationEventPublisher的 publishEvent 方法,发布 UserArrearsEvent 事件。

3、观察者 EmailService

/**
 *  观察者 邮箱欠费通知
 */
@Service
public class EmailService implements ApplicationListener<UserArrearsEvent> {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    @Async
    public void onApplicationEvent(UserArrearsEvent event) {
        logger.info("邮箱欠费通知,你好 {} ,请尽快缴费啊啊啊啊!", event.getUsername());
    }
}
  1. 实现 ApplicationListener 接口,通过 E 泛型设置感兴趣的事件。

  2. 实现 onApplicationEvent方法,针对监听的 UserRegisterEvent 事件,进行自定义处理。

  3. 设置 @Async 注解,那就代表走异步操作。同时需要在启动类上添加@EnableAsync,这样异步才生效。

4、观察者 SmsService

/**
 *  短信欠费通知
 */
@Service
public class SmsService {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @EventListener
    public void smsArrears(UserArrearsEvent event) {
        logger.info("短信欠费通知,你好 {} ,请尽快缴费啊啊啊啊!", event.getUsername());
    }
}

这里提供另一种方式,就是在方法上,添加 @EventListener 注解,并设置监听的事件为 UserRegisterEvent。

5、接口测试

/**
 *  测试 Sping Event观察者模式
 */
@RestController
@RequestMapping("/test")
public class DemoController {

    @Autowired
    private UserArrearsService userArrearsService;

    @GetMapping("/arrears")
    public String arrears(String username) {
        userArrearsService.arrears(username);
        return "成功";
    }
}

日志输出

被观察者 用户欠费,用户名称 = 张老三
短信欠费通知,你好 张老三 ,请尽快缴费啊啊啊啊!
邮箱欠费通知,你好 张老三 ,请尽快缴费啊啊啊啊!

成功!

GitHub地址:https://github.com/yudiandemingzi/spring-boot-study

 

作者|binron文章来源地址https://www.toymoban.com/news/detail-710341.html

到了这里,关于Spring Event 观察者模式, 业务解耦神器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 观察者模式(上):详解各种应用场景下观察者模式的不同实现方式

            从今天起,我们开始学习行为型设计模式。我们知道,创建型设计模式主要解决“对象的创建”问题,结构型设计模式主要解决“类或对象的组合或组装”问题,那行为型设计模式主要解决的就是“ 类或对象之间的交互 ”问题。 原理及应用场景剖析 在对象之间

    2024年02月16日
    浏览(57)
  • 【C++ 观察者模式 思想理解】C++中的观察者模式:松耦合设计与动态交互的艺术,合理使用智能指针观察者

    在进入技术细节之前,理解观察者模式(Observer Pattern)的基本概念和它在现代编程中的重要性是至关重要的。 观察者模式是一种设计模式,它定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。在C++中,这个

    2024年01月24日
    浏览(56)
  • 行为型模式 | 观察者模式

    观察者模式又叫做发布-订阅(Publish/Subscribe)模式,定义了一种一对多的依赖关系 。让多个观察者对象同时监听某一个主题对象,这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。 软件系统常常要求在某一个对象的状态发生变化的时候

    2024年01月22日
    浏览(79)
  • 【设计模式】观察者模式

    观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。 Subject:抽象主题(被观察者

    2024年02月13日
    浏览(52)
  • 设计模式——观察者模式

    观察者模式可以分为观察者和被观察者,观察者通过注册到一个被观察者中,也可视为订阅,当被观察者的数据发生改变时,会通知到观察者,观察者可以据此做出反应。 可以类比订阅报纸,报社就是被观察者,订阅者就是观察者,订阅者通过订阅报纸与报社建立联系,而报

    2024年02月15日
    浏览(53)
  • 设计模式-观察者模式

    观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新。当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者

    2024年02月15日
    浏览(58)
  • 设计模式---观察者模式

    1,概念         属于行为模式的一种,定义了一种一对多的依赖关系,让多个观察者对象同时监听某一对象主题对象,这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。 在观察者模式中有如下角色: Subject:抽象主题(抽象被观察者),

    2024年02月15日
    浏览(65)
  • 设计模式:观察者模式

    定义 观察者模式(Observer Pattern)是一种行为设计模式,允许一个对象(称为“主题”或“可观察对象”)维护一组依赖于它的对象(称为“观察者”),当主题的状态发生变化时,会自动通知所有观察者对象。 应用场景 观察者模式适用于以下场景: 联动反应 :当一个对象

    2024年04月08日
    浏览(59)
  • 重温设计模式 --- 观察者模式

    观察者模式 是一种行为型设计模式,它允许对象之间建立一种一对多的关系,使得当一个对象状态改变时,所有依赖它的对象都能够自动得到通知并更新自己的状态。该模式可以帮助我们实现松耦合的系统,以便更好地应对变化和扩展。 在观察者模式中,有两个角色: 观察

    2024年02月13日
    浏览(59)
  • 设计模式(11)观察者模式

    一、概述: 1、定义:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。 2、结构图: 实现  调用

    2024年02月11日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包