行为型-观察者模式
2026/1/15大约 3 分钟Java设计模式行为型模式观察者模式Java设计模式面向对象架构设计最佳实践代码优化
概述
观察者模式(Observer Pattern)定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
适用场景
- 一个对象的改变需要同时改变其他对象
- 一个对象必须通知其他对象,而并不知道这些对象是谁
- 需要在系统中创建一个触发链
角色组成
- Subject(抽象主题):被观察者,维护观察者列表
- ConcreteSubject(具体主题):具体被观察者
- Observer(抽象观察者):定义更新接口
- ConcreteObserver(具体观察者):实现更新方法
代码实现
1. 抽象观察者
public interface Observer {
void update(String message);
}2. 抽象主题
public interface Subject {
void attach(Observer observer);
void detach(Observer observer);
void notifyObservers(String message);
}3. 具体主题
public class WeChatAccount implements Subject {
private String name;
private List<Observer> observers = new ArrayList<>();
public WeChatAccount(String name) {
this.name = name;
}
@Override
public void attach(Observer observer) {
observers.add(observer);
}
@Override
public void detach(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers(String message) {
System.out.println(name + " 发布: " + message);
for (Observer observer : observers) {
observer.update(message);
}
}
}4. 具体观察者
public class WeChatUser implements Observer {
private String name;
public WeChatUser(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name + " 收到消息: " + message);
}
}5. 客户端
public class Client {
public static void main(String[] args) {
WeChatAccount account = new WeChatAccount("技术公众号");
Observer user1 = new WeChatUser("张三");
Observer user2 = new WeChatUser("李四");
Observer user3 = new WeChatUser("王五");
account.attach(user1);
account.attach(user2);
account.attach(user3);
account.notifyObservers("新文章:设计模式详解");
System.out.println();
account.detach(user2);
account.notifyObservers("新文章:Java并发编程");
}
}# 输出
技术公众号 发布: 新文章:设计模式详解
张三 收到消息: 新文章:设计模式详解
李四 收到消息: 新文章:设计模式详解
王五 收到消息: 新文章:设计模式详解
技术公众号 发布: 新文章:Java并发编程
张三 收到消息: 新文章:Java并发编程
王五 收到消息: 新文章:Java并发编程类图
JDK 中的应用
// java.util.Observable(已废弃)
// 推荐使用 PropertyChangeListener
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
public class Person {
private PropertyChangeSupport support = new PropertyChangeSupport(this);
private String name;
public void addPropertyChangeListener(PropertyChangeListener listener) {
support.addPropertyChangeListener(listener);
}
public void setName(String name) {
String oldName = this.name;
this.name = name;
support.firePropertyChange("name", oldName, name);
}
}Spring 事件机制
// 自定义事件
public class UserRegisterEvent extends ApplicationEvent {
private String username;
public UserRegisterEvent(Object source, String username) {
super(source);
this.username = username;
}
}
// 事件监听器
@Component
public class UserRegisterListener implements ApplicationListener<UserRegisterEvent> {
@Override
public void onApplicationEvent(UserRegisterEvent event) {
System.out.println("用户注册: " + event.getUsername());
}
}
// 发布事件
@Service
public class UserService {
@Autowired
private ApplicationEventPublisher publisher;
public void register(String username) {
publisher.publishEvent(new UserRegisterEvent(this, username));
}
}优缺点
优点:
- 观察者和被观察者是抽象耦合的
- 建立一套触发机制
缺点:
- 如果观察者很多,通知会花费很多时间
- 循环依赖可能导致系统崩溃
