目录
一、简介
**观察者模式(Observer Pattern)**是一种行为设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生变化时,其所有依赖者(观察者)都会自动收到通知并进行更新。
在观察者模式中,存在两类角色:
- 主题(Subject): 也称为被观察者或可观察对象,维护了一组观察者对象,并提供了添加、删除和通知观察者的方法。
- 观察者(Observer): 也称为订阅者,定义了一个更新接口或抽象类,用于接收主题的通知并进行相应的处理。
主题维护了一个观察者列表,当其内部状态发生变化时,会通知所有注册的观察者对象,使它们能够根据主题状态的变化进行相应的更新或处理。
观察者模式将主题和观察者解耦,使得主题和观察者之间的依赖关系变得松散,同时也提高了系统的灵活性和可扩展性。这种模式常用于订阅/发布系统、事件驱动系统以及需要一对多依赖关系的场景中。
二、观察者模式
下面是一个稍微复杂一些的观察者模式的示例,多个不同的观察者监听某个事件,并根据事件执行不同的操作(发送短信、发送邮件等):
2.1、事件接口及其实现
java
// 事件接口
public interface Event {
String getEventData();
}
// 具体事件类
public class ConcreteEvent implements Event {
private String eventData;
public ConcreteEvent(String data) {
this.eventData = data;
}
@Override
public String getEventData() {
return eventData;
}
}
2.2、观察者接口及其实现
java
// 观察者接口
public interface Observer {
void update(Event event);
}
// 具体观察者 -- 邮件
public class EmailObserver implements Observer {
@Override
public void update(Event event) {
System.out.println("发送邮件: " + event.getEventData());
}
}
// 具体观察者 -- 短信
public class SMSObserver implements Observer {
@Override
public void update(Event event) {
System.out.println("发送短信: " + event.getEventData());
}
}
2.3、主题接口及其实现
java
// 主题接口
public interface Subject {
void attach(Observer observer);
void detach(Observer observer);
void notifyObservers(Event event);
}
import java.util.ArrayList;
import java.util.List;
// 具体主题
public class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
@Override
public void attach(Observer observer) {
observers.add(observer);
}
@Override
public void detach(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers(Event event) {
for (Observer observer : observers) {
observer.update(event);
}
}
}
2.4、使用
java
public class ObserverPatternExample {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
Observer smsObserver = new SMSObserver();
Observer emailObserver = new EmailObserver();
subject.attach(smsObserver);
subject.attach(emailObserver);
Event event = new ConcreteEvent("你正在登录账户,查看Alian的博客");
subject.notifyObservers(event);
}
}
运行结果:
发送短信: 你正在登录账户,查看Alian的博客
发送邮件: 你正在登录账户,查看Alian的博客
三、优点与缺点
观察者模式具有以下优点和缺点:
优点
- 解耦和灵活性: 主题和观察者之间的关系是松散耦合的,主题无需知道观察者的细节,使得系统更加灵活,能够方便地扩展和维护。
- 一对多的依赖关系: 允许一个主题对象同时与多个观察者对象建立联系,当主题状态发生变化时,所有依赖于它的观察者都会得到通知。
- 支持广播通信: 观察者模式支持广播通信机制,主题对象发出的通知会被所有相关的观察者接收。
缺点
- 可能导致系统性能下降: 如果观察者过多或者操作复杂,通知所有观察者可能会影响性能。
- 可能导致循环依赖: 观察者和主题之间的循环依赖可能会导致系统问题,需要小心设计以避免这种情况。
- 可能引起内存泄漏: 如果观察者对象未被正确地移除,可能会导致内存泄漏问题。
总的来说,观察者模式是一种灵活、解耦的设计模式,能够实现对象间的一对多依赖关系。然而,在使用时需注意控制观察者数量、避免循环依赖和及时移除不需要的观察者,以确保系统的性能和稳定性。这个模式应用很广泛,比如springboot源码的事件发布机制。