跳转到正文
宋柏成
返回

观察者模式

观察者模式

什么是观察者模式

观察者模式也被称为发布-订阅模式或者事件-监听模式,这让我们很容易联想到 Redis、MQ 中的发布订阅模式,即主题对象(发布者)和观察者对象(订阅者)之间的关系类似于发布者发布事件,而观察者监听并响应该事件的方式,所以观察者模常用于实现对象之间的一对多依赖关系。

实现

大多数编程语言都支持观察者模式的实现,但是大多数的场景下并不会去使用,因为其实现存在一些问题和局限性,不符合现代Java语言的设计原则和最佳实践。另外,它们也没有提供对并发编程的良好支持。拿 Java举例,Java 官方推荐使用其他更好的替代方案,例如使用接口和回调机制来实现观察者模式,或者使用第三方的观察者模式框架(如 Spring Framework 的事件机制或 Google Guava 的事件总线)。

jdk版

在 Java 标准库中,java.util.Observable 类和 java.util.Observer 接口在 Java 9 版本之后被标记为过时,可能会在未来的 Java 版本中被移除,但是这并不影响我们用在这里方便理解其过程。

  1. 首先,创建一个发布者类。
// 发布者接口
interface Publisher {
    void subscribe(Subscriber subscriber);
    void unsubscribe(Subscriber subscriber);
    void notifySubscribers(String message);
}

// 具体的发布者类
class ConcretePublisher implements Publisher {
    private List<Subscriber> subscribers;

    public ConcretePublisher() {
        subscribers = new ArrayList<>();
    }

    @Override
    public void subscribe(Subscriber subscriber) {
        subscribers.add(subscriber);
    }

    @Override
    public void unsubscribe(Subscriber subscriber) {
        subscribers.remove(subscriber);
    }

    @Override
    public void notifySubscribers(String message) {
        for (Subscriber subscriber : subscribers) {
            subscriber.receiveMessage(message);
        }
    }

    public void publish(String message) {
        notifySubscribers(message);
    }
}
  1. 创建订阅者类。
// 订阅者接口
interface Subscriber {
    void receiveMessage(String message);
}

// 具体的订阅者类
class ConcreteSubscriber implements Subscriber {
    private String name;

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

    @Override
    public void receiveMessage(String message) {
        System.out.println(name + " 收到消息: " + message);
    }
}
  1. 创建一个具体的发布者和两个具体的订阅者来测试。
public class ObserverPatternExample {
    public static void main(String[] args) {
        ConcretePublisher publisher = new ConcretePublisher();

        ConcreteSubscriber subscriber1 = new ConcreteSubscriber("订阅者1");
        ConcreteSubscriber subscriber2 = new ConcreteSubscriber("订阅者2");

        publisher.subscribe(subscriber1);
        publisher.subscribe(subscriber2);

        publisher.publish("Hello, World!");

        publisher.unsubscribe(subscriber2);

        publisher.publish("How are you?");
    }
}

运行上述代码时,一开始订阅者订阅了两个发布者,并且在发布者发布消息时接收到通知。然后,我们取消了一个订阅者的订阅,并再次发布消息,观察到只有一个订阅者收到了通知。

Spring版

在Spring框架的观察者模式中我们首先要了解一些核心概念:

接下来我们使用 Spring Framework 的事件机制重写这个例子:

  1. 首先,我们定义一个事件类 MyEvent,它将作为观察者模式中的事件对象。
public class MyEvent extends ApplicationEvent {

    private String message;

    public MyEvent(Object source, String message) {

        super(source);
        this.message = message;
    }

    public String getMessage() {

        return message;
    }
}
  1. 接下来,创建一个事件源类MyEventPublisher,负责发布事件。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;

@Component
public class MyEventPublisher {

    @Autowired
    private ApplicationEventPublisher eventPublisher;

    public void publishEvent(String message) {

        CustomEvent customEvent = new CustomEvent(this, message);
        eventPublisher.publishEvent(customEvent);
    }
}
  1. 最后,创建一个事件监听器类MyEventListener,用于接收和处理事件:
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

@Component
public class MyEventListener implements ApplicationListener<MyEvent> {

    @Override
    public void onApplicationEvent(CustomEvent event) {

        String message = event.getMessage();
        // 在这里处理事件
        System.out.println("收到消息:" + message);
    }
}

在这个示例中,通过 MyEventPublisher 发布了一个自定义事件。当事件发生时,MyEventListener 监听器将接收到该事件,并处理相应的逻辑。需要注意的是,需要使用 @Component 注解将事件发布器和事件监听器声明为 Spring 容器中的组件,以便自动注册和管理。

总结

观察者模式适用于以下场景:


分享这篇文章:

上一篇
反射
下一篇
其他技能