返回
观察者模式与发布/订阅模式的差异分析及代码实现
前端
2023-10-28 13:16:17
概念
观察者模式
观察者模式是一种软件设计模式,它定义了一种一对多的依赖关系,其中一个对象(称为“主题”)可以通知多个对象(称为“观察者”)它的状态或事件的变化。当主题的状态或事件发生变化时,它会自动通知所有观察者,以便它们可以相应地更新自己。
发布/订阅模式
发布/订阅模式是一种软件设计模式,它定义了一种一对多的通信机制,其中一个对象(称为“发布者”)可以将消息发送给多个对象(称为“订阅者”),而无需知道订阅者的具体身份或数量。发布者只负责将消息发送给中间媒介(称为“消息代理”),而订阅者只需要向消息代理注册自己的兴趣,即可收到相关消息。
场景
观察者模式通常用于以下场景:
- 当一个对象的状态或事件发生变化时,需要通知多个其他对象。
- 当需要在多个对象之间建立松耦合的关系时。
- 当需要在系统中实现可扩展性和灵活性时。
发布/订阅模式通常用于以下场景:
- 当需要在多个对象之间建立松耦合的关系时。
- 当需要在系统中实现可扩展性和灵活性时。
- 当需要将消息从一个对象发送到多个对象,而无需知道接收者的具体身份或数量时。
优缺点比较
特性 | 观察者模式 | 发布/订阅模式 |
---|---|---|
耦合性 | 中等 | 松散 |
可扩展性 | 良好 | 优秀 |
灵活性 | 良好 | 优秀 |
性能 | 良好 | 优秀 |
易用性 | 适中 | 容易 |
场景 | 当需要在多个对象之间建立松耦合的关系时。 | 当需要将消息从一个对象发送到多个对象,而无需知道接收者的具体身份或数量时。 |
实现思路
观察者模式
观察者模式的实现思路如下:
- 定义一个抽象主题类,该类负责管理观察者列表。
- 定义一个抽象观察者类,该类定义了更新方法,用于接收主题的状态或事件变化通知。
- 定义具体主题类,继承抽象主题类,并实现其方法。
- 定义具体观察者类,继承抽象观察者类,并实现其方法。
- 将具体观察者添加到具体主题的观察者列表中。
- 当主题的状态或事件发生变化时,通知所有观察者。
发布/订阅模式
发布/订阅模式的实现思路如下:
- 定义一个消息代理类,该类负责管理发布者和订阅者列表。
- 定义一个发布者类,该类负责向消息代理发送消息。
- 定义一个订阅者类,该类负责向消息代理注册自己的兴趣,并接收相关消息。
- 当发布者向消息代理发送消息时,消息代理将消息发送给所有订阅者。
代码示例
观察者模式
// 主题接口
interface Subject {
void addObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
// 具体主题类
class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
@Override
public void addObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update();
}
}
// 其他方法...
}
// 观察者接口
interface Observer {
void update();
}
// 具体观察者类
class ConcreteObserver1 implements Observer {
@Override
public void update() {
// 具体更新逻辑...
}
}
class ConcreteObserver2 implements Observer {
@Override
public void update() {
// 具体更新逻辑...
}
}
// 使用示例
public class Main {
public static void main(String[] args) {
Subject subject = new ConcreteSubject();
Observer observer1 = new ConcreteObserver1();
Observer observer2 = new ConcreteObserver2();
subject.addObserver(observer1);
subject.addObserver(observer2);
subject.notifyObservers();
}
}
发布/订阅模式
// 消息代理类
class MessageBroker {
private Map<String, List<Subscriber>> subscribers = new HashMap<>();
public void publish(String topic, Message message) {
List<Subscriber> subscribers = this.subscribers.get(topic);
if (subscribers != null) {
for (Subscriber subscriber : subscribers) {
subscriber.receive(message);
}
}
}
public void subscribe(String topic, Subscriber subscriber) {
List<Subscriber> subscribers = this.subscribers.get(topic);
if (subscribers == null) {
subscribers = new ArrayList<>();
this.subscribers.put(topic, subscribers);
}
subscribers.add(subscriber);
}
public void unsubscribe(String topic, Subscriber subscriber) {
List<Subscriber> subscribers = this.subscribers.get(topic);
if (subscribers != null) {
subscribers.remove(subscriber);
}
}
}
// 发布者类
class Publisher {
private MessageBroker messageBroker;
public Publisher(MessageBroker messageBroker) {
this.messageBroker = messageBroker;
}
public void publish(String topic, Message message) {
messageBroker.publish(topic, message);
}
}
// 订阅者类
class Subscriber {
private String topic;
public Subscriber(String topic) {
this.topic = topic;
}
public void receive(Message message) {
// 具体处理逻辑...
}
}
// 使用示例
public class Main {
public static void main(String[] args) {
MessageBroker messageBroker = new MessageBroker();
Publisher publisher = new Publisher(messageBroker);
Subscriber subscriber1 = new Subscriber("topic1");
Subscriber subscriber2 = new Subscriber("topic2");
messageBroker.subscribe("topic1", subscriber1);
messageBroker.subscribe("topic2", subscriber2);
publisher.publish("topic1", new Message("Hello, world!"));
publisher.publish("topic2", new Message("Goodbye, world!"));
}
}
实际用法
观察者模式和发布/订阅模式都是非常有用的设计模式,它们在许多实际应用中都有着广泛的应用。以下是一些实际用法示例:
- 观察者模式:
- GUI编程:观察者模式可以用来实现GUI组件之间的通信,当一个GUI组件发生变化时,其他GUI组件可以自动更新。
- 事件处理:观察者模式可以用来实现事件处理,当一个事件发生时,可以通知所有感兴趣的事件处理程序。
- 状态管理:观察者模式可以用来实现状态管理,当一个对象的状态发生变化时,可以通知所有感兴趣的对象。
- 发布/订阅模式:
- 消息传递:发布/订阅模式可以用来实现消息传递,发布者可以将消息发送给所有订阅者,而无需知道订阅者的具体身份或数量。
- 事件处理:发布/订阅模式可以用来实现事件处理,当一个事件发生时,可以通知所有感兴趣的事件处理程序。
- 负载均衡:发布/订阅模式可以用来实现负载均衡,将任务分配给多个工作者节点。
总结
观察者模式和发布/订阅模式都是非常有用的设计模式,它们都有各自的优缺点和适用场景。在实际应用中,需要根据具体情况选择合适的模式。