Guava、Spring 如何抽象观察者模式?(一)

Handpc
发布于 2022-6-23 17:07
浏览
0收藏

 

前言
《设计模式实战》系列目前已经写了 7 篇了,最近几篇平均阅读保持 1.1k+,后面也会延续之前的高质量,欢迎继续关注

  • 【设计模式实战】策略模式
  • 【设计模式实战】责任链模式
  • 【设计模式实战】Builder 模式
  • 【设计模式实战】代理模式
  • 【设计模式实战】模版方法模式
  • 【设计模式实战】适配器模式
  • 【设计模式实战】...
    今天讲解一篇行为型设计模式,什么是行为型?行为型主要负责设计 类或对象之间的交互。工作中常用的观察者模式就是一种行为型设计模式

 

最近在尝试重构之前写过的代码。在重新梳理过业务之后,发现已有的设计场景应该能够接入到设计模式,而且查看了代码的提交记录,更是坚定了此想法

 

保持之前的一贯作风,想要说明一个设计模式,需要三板斧支撑。什么是观察者模式?如何使用观察者模式?项目中应该如何应用?

 

观察者设计模式大纲如下:

  1. 什么是观察者模式
  2. 观察者模式代码如何写
  3. 如何使用观察者模式结合业务
  4. Guava EventBus 观察者模式
  5. Spring ApplicationEvent 事件模型
  6. 观察者模式最后的总结


什么是观察者模式
观察者模式 是一种行为设计模式,允许定义一种订阅通知机制,可以在对象(被观察者)事件发生时通知多个 “观察” 该对象的观察者对象,所以也被称为 发布订阅模式

 

其实我个人而言,不太喜欢使用文字去定义一种设计模式的语义,因为这样总是难以理解。所以就有了下面生活中的例子,来帮助读者更好的去理解模式的语义。类图如下所示:

 Guava、Spring 如何抽象观察者模式?(一)-鸿蒙开发者社区
在举例说明前,先让我们熟悉下观察者模式中的 角色类型 以及代码示例。观察者模式由以下几部分角色组成,可以参考代码示例去理解,不要被文字描述带偏

  • 主题(被观察者)(Subject):抽象主题角色把所有观察者对象保存在一个容器里,提供添加和移除观察者接口,并且提供出通知所有观察者对象接口(也有作者通过 Observable 描述)
  • 具体主题(具体被观察者)(Concrete Subject):具体主题角色的职责就是实现抽象目标角色的接口语义,在被观察者状态更改时,给容器内所有注册观察者发送状态通知
    public interface Subject {
        void register(Observer observer);  // 添加观察者
        void remove(Observer observer);  // 移除观察者
        void notify(String message);  // 通知所有观察者事件
    }
    
    public class ConcreteSubject implements Subject {
        private static final List<Observer> observers = new ArrayList();
    
        @Override
        public void register(Observer observer) { observers.add(observer); }
    
        @Override
        public void remove(Observer observer) { observers.remove(observer); }
    
        @Override
        public void notify(String message) { observers.forEach(each -> each.update(message)); }
    }​
  • 抽象观察者(Observer):抽象观察者角色是观察者的行为抽象,它定义了一个修改接口,当被观察者发出事件时通知自己
  • 具体观察者(Concrete Observer):实现抽象观察者定义的更新接口,可以在被观察者发出事件时通知自己
    public interface Observer {
        void update(String message);  // String 入参只是举例, 真实业务不会限制
    }
    
    public class ConcreteObserverOne implements Observer {
        @Override
        public void update(String message) {
            // 执行 message 逻辑
            System.out.println("接收到被观察者状态变更-1");
        }
    }
    
    public class ConcreteObserverTwo implements Observer {
        @Override
        public void update(String message) {
            // 执行 message 逻辑
            System.out.println("接收到被观察者状态变更-2");
        }
    }​

我们跑一下上面的观察者模式示例,如果不出意外的话会将两个观察者执行逻辑中的日志打印输出。如果是平常业务逻辑,抽象观察者定义的入参是具有业务意义的,大家可以类比项目上使用到的 MQ Message 机制

public class Example {
    public static void main(String[] args) {
        ConcreteSubject subject = new ConcreteSubject();
        subject.register(new ConcreteObserverOne());
        subject.register(new ConcreteObserverTwo());
        subject.notify("被观察者状态改变, 通知所有已注册观察者");
    }
}

 

文章转自公众号:龙台的技术笔记

已于2022-6-23 17:07:55修改
收藏
回复
举报
回复
    相关推荐