观察者模式是一种行为设计模式,它允许一个对象(称为主题或可观察者)维护一系列依赖于它的对象(称为观察者),当主题的状态发生变化时,它会自动通知所有的观察者。这种模式被广泛应用于实现对象之间的松耦合,其中主题和观察者之间的关系是动态的。
下面根据一些常见场景一起来了解一下什么是观察者模式
事件处理和消息传递示例
首先我们定义一个事件
// 定义事件
class Event {
private String message;
public Event(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
然后再定义一个事件处理器
// 定义事件处理器
interface EventHandler {
void handleEvent(Event event);
}
接着我们实现这个事件处理器
// 具体的事件处理器
class ConcreteEventHandler implements EventHandler {
private String name;
public ConcreteEventHandler(String name) {
this.name = name;
}
@Override
public void handleEvent(Event event) {
System.out.println(name + " handles event: " + event.getMessage());
}
}
最后我们需要一个总线来维护所有的事件处理器
import java.util.ArrayList;
import java.util.List;
// 事件总线
class EventBus {
private List<EventHandler> eventHandlers = new ArrayList<>();
// 注册事件处理器
public void registerEventHandler(EventHandler eventHandler) {
eventHandlers.add(eventHandler);
}
// 发布事件
public void publishEvent(Event event) {
for (EventHandler handler : eventHandlers) {
handler.handleEvent(event);
}
}
}
测试一下
public class Test {
public static void main(String[] args) {
// 创建事件总线
EventBus eventBus = new EventBus();
// 创建事件处理器
EventHandler eventHandler1 = new ConcreteEventHandler("Event Handler 1");
EventHandler eventHandler2 = new ConcreteEventHandler("Event Handler 2");
// 注册事件处理器
eventBus.registerEventHandler(eventHandler1);
eventBus.registerEventHandler(eventHandler2);
// 创建事件
Event event = new Event("Sample Event");
// 发布事件
eventBus.publishEvent(event);
}
}
运行结果
可以发现当事件发布时,所有注册的事件处理器都会收到通知,并处理相应的事件。
可能也有人发现了这不就是MQ吗,理论上来说这个的确是mq的一种简单实现方式,当然实际应用中我们一般会引用第三方框架比如RabbitMQ和SocketMQ等
发布-订阅机制示例
一样的还是先定义一个事件
// 定义事件
class Event {
private String message;
public Event(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
然后我们来一个消息订阅者
// 定义订阅者
interface Subscriber {
void receive(Event event);
}
实现订阅者具体操作
// 具体订阅者
class ConcreteSubscriber implements Subscriber {
private String name;
public ConcreteSubscriber(String name) {
this.name = name;
}
@Override
public void receive(Event event) {
System.out.println(name + " received message: " + event.getMessage());
}
}
我们还需要一个发布消息的人
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
// 定义发布者
class Publisher {
private Map<String, List<Subscriber>> topics = new HashMap<>();
// 订阅事件
public void subscribe(String topic, Subscriber subscriber) {
topics.computeIfAbsent(topic, k -> new ArrayList<>()).add(subscriber);
}
// 发布事件
public void publish(String topic, Event event) {
List<Subscriber> subscribers = topics.getOrDefault(topic, new ArrayList<>());
for (Subscriber subscriber : subscribers) {
subscriber.receive(event);
}
}
}
测试一下
public class Test {
public static void main(String[] args) {
// 创建发布者
Publisher publisher = new Publisher();
// 创建订阅者
Subscriber subscriber1 = new ConcreteSubscriber("Subscriber 1");
Subscriber subscriber2 = new ConcreteSubscriber("Subscriber 2");
Subscriber subscriber3 = new ConcreteSubscriber("Subscriber 3");
// 订阅事件
publisher.subscribe("topic1", subscriber1);
publisher.subscribe("topic2", subscriber2);
publisher.subscribe("topic2", subscriber3);
// 发布事件
publisher.publish("topic1", new Event("Message 1 for topic1"));
publisher.publish("topic2", new Event("Message 2 for topic2"));
}
}
运行结果
这个就更像MQ的消息队列模式了,我们可以将订阅者和消息队列绑定在一起,然后给不同的队列推送不同的事件由不同的订阅者去处理