【设计模式】聊聊观察者设计模式原理及应用

原理

观察者模式属于行为模式,行为模式主要解决类和对象之间交互问题。
含义:在对象之间定义一个一对多的依赖,当一个对象状态改变时,所有依赖的对象会自动通知。

被依赖的对象被观察者(Observable) ,依赖的对象观察者(Observer),当然也可以叫发布-订阅等。
在这里插入图片描述

一个case

比如我们维护的用户中心,当用户进行注册的时候,就进行通知发送短信、WA、邮件等。

1.第一步,先定义被观察者接口,主要就是注册、删除、已经通知观察者。

/**
 * @author qxlx
 * @date 2024/4/13 22:25
 */
public interface Subject {

    /**
     * 注册
     * @param observer
     */
    void registerObserver(Observer observer);

    /**
     * 删除
     * @param observer
     */
    void deleteObserver(Observer observer);

    /**
     * 发送事件
     * @param message
     */
    void notifyObservers(String message);
}

2.定义贯彻者具体的行为

public interface Observer {

    void notify(String message);

}

3.被观察者的具体实现,可以发送通过接口注册或删除观察者,当被观察者执行用户注册的方法时,就会触发通知观察者进行处理。
这里需要明确下,可以采用同步的方式 或者异步方式。因为对于注册接口来说响应时间还是比较重要的,采用线程的方式 可以提高接口性能。

/**
 * @author qxlx
 * @date 2024/4/13 22:27
 */
public class ConcreteSubject implements Subject {

    private List<Observer> observerList = new CopyOnWriteArrayList<>();

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

    @Override
    public void deleteObserver(Observer observer) {
        observerList.remove(observer);
    }

    @Override
    public void notifyObservers(String message) {
        // 1.同步调用
        // 2.异步非阻塞
        observerList.forEach(o -> o.notify(message));

        // new Thread()
        new Thread(() -> {
            observerList.forEach(o -> o.notify(message));
        }).start();

        // 线程池
        ThreadPoolUtil.getThreadPool(10).
                execute(() -> observerList.forEach(o -> o.notify(message)));

    }
}

4.定义具体的观察者实现类,发送邮件 或者发送wa

public class UserSendEmailObserver implements Observer{

    @Override
    public void notify(String message) {
        System.out.println("用户注册成功,发送邮件通知!");
    }

}

public class UserWaSendObserver implements Observer{

    @Override
    public void notify(String message) {
        System.out.println("用户注册成功,发送了wa通知");
    }
}

最终的Demo 其实就是这样,将观察者添加到被观察者上,观察者一旦执行了用户注册,就会触发对应动作,比如说新增新的动作,那么就可以直接添加一个发优惠卷的观察者。可以很好的进行拓展。

    public static void main(String[] args) {
        UserSendEmailObserver userSendEmailObserver = new UserSendEmailObserver();
        UserWaSendObserver userWaSendObserver = new UserWaSendObserver();
        ConcreteSubject concreteSubject = new ConcreteSubject();

        concreteSubject.registerObserver(userSendEmailObserver);
        concreteSubject.registerObserver(userWaSendObserver);

        concreteSubject.notifyObservers("register");
    }

在这里插入图片描述

Spring 中如何应用观察者模式

在spring源码中,IOC容器进行初始化的过程中,refresh() 方法中就包含观察者模式。而Spring进行了抽象,也就是将观察者和被观察者 进行调整成多播器和监听器,通过事件来驱动监听器的执行。
在这里插入图片描述
在这里插入图片描述

可以看到,整体的流程就是,初始化多播器对象,SimpleApplicationEventMulticaster,将监听器添加到多播器中。然后发布事件,调用监听器进行处理。可以发现其实设计模式在实际的应用中,思想相同的,但是落地的时候都有自己的调整。本质上还是当多个对象所依赖的对象有对应的事件时,需要做对应的动作。解耦合观察者和被观察者。

	//初始化事件多播功能(事件派发) Initialize event multicaster for this context.
	//初始化多播器 SimpleApplicationEventMulticaster 注册到IOC容器中
	initApplicationEventMulticaster();

	//注册监听器,从容器中获取所有的ApplicationListener;
	// Check for listener beans and register them.
	registerListeners();

	//发布事件 Last step: publish corresponding event.
	finishRefresh();

相关推荐

  1. 设计模式观察模式

    2024-04-20 22:36:01       39 阅读
  2. 设计模式观察模式

    2024-04-20 22:36:01       33 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-20 22:36:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-20 22:36:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-20 22:36:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-20 22:36:01       20 阅读

热门阅读

  1. Spring Cloud Gateway面试题

    2024-04-20 22:36:01       53 阅读
  2. Ubuntu如何给tar.gz文件创建桌面快捷方式

    2024-04-20 22:36:01       51 阅读
  3. 力扣经典150题第三十三题:最小覆盖子串

    2024-04-20 22:36:01       19 阅读
  4. 多数元素(C++)

    2024-04-20 22:36:01       13 阅读
  5. SpringMVC接收参数方式讲解

    2024-04-20 22:36:01       16 阅读