观察者模式(Observer Pattern)
观察者模式是一种行为设计模式,它定义了对象之间的一对多依赖关系,使得当一个对象改变状态时,所有依赖于它的对象都会得到通知并自动更新。
概念
- 主题(Subject):维护一系列观察者,提供用于增加或删除观察者的方法。
- 观察者(Observer):为那些在主题状态发生改变时需获得通知的对象定义一个更新接口。
- 具体主题(Concrete Subject):在状态发生改变时,向其注册的观察者发出通知。
- 具体观察者(Concrete Observer):实现观察者接口,以便在主题状态改变时更新自己的状态。
优点
- 支持广播通信:观察者模式允许消息的广播,便于实现一对多的通信。
- 实现了主题和观察者之间的抽象耦合:主题只知道观察者列表,不需要知道具体的观察者,便于扩展。
- 支持即时或延迟通知:观察者可以即时获得状态改变的通知,或根据需要延迟处理。
缺点
- 可能会导致无意的循环引用:观察者和主题之间的复杂依赖关系可能会导致循环引用问题,增加系统复杂性。
- 如果观察者响应不当,可能会导致错误或性能问题:观察者的处理函数出错或处理时间过长,会影响整个系统的效率和稳定性。
Java代码示例
假设我们有一个简单的股票价格更新系统,其中的价格更新会通知所有注册的观察者。
java复制代码
import java.util.ArrayList;
import java.util.List;
// 主题接口
interface Subject {
void attach(Observer observer);
void detach(Observer observer);
void notifyUpdate(Message m);
}
// 观察者接口
interface Observer {
void update(Message m);
}
// 具体主题
class StockTicker implements Subject {
private final List<Observer> observers = new ArrayList<>();
public void attach(Observer observer) {
observers.add(observer);
}
public void detach(Observer observer) {
observers.remove(observer);
}
public void notifyUpdate(Message m) {
for (Observer observer : observers) {
observer.update(m);
}
}
}
// 具体观察者
class PriceDisplay implements Observer {
public void update(Message m) {
System.out.println("PriceDisplay: " + m.getContent());
}
}
class Message {
private final String content;
public Message(String content) {
this.content = content;
}
public String getContent() {
return content;
}
}
// 客户端代码
public class ObserverDemo {
public static void main(String[] args) {
StockTicker ticker = new StockTicker();
PriceDisplay display = new PriceDisplay();
ticker.attach(display);
ticker.notifyUpdate(new Message("AAPL 150.50"));
ticker.notifyUpdate(new Message("GOOGL 1200.30"));
}
}
在这个例子中,StockTicker
类是具体主题,它维护一个观察者列表并通知它们状态的改变。PriceDisplay
类是具体观察者,它实现了 Observer
接口,并在接收到更新通知时展示股票价格。这样,股票价格的任何更新都会自动通知给 PriceDisplay
,实现了数据与视图的分离。