1. 观察者模式概述
观察者模式(Observer Pattern)是一种行为设计模式,它定义了一种一对多的依赖关系,让多个观察者对象可以同时监听并收到被观察对象的状态变化通知,以保持对象之间的数据同步。
观察者模式涉及以下角色:
- 主题(Subject):也叫做被观察者,维护一组观察者对象,提供方法用于注册和删除观察者,以及通知观察者更新状态。
- 观察者(Observer):定义一个更新方法,用于在主题状态改变时接收通知。观察者可以注册到一个或多个主题。
- 具体主题(Concrete Subject):实现主题接口,负责维护观察者列表,并在状态改变时通知观察者。
- 具体观察者(Concrete Observer):实现观察者接口中的更新方法,以实际响应主题状态变化。
观察者模式的优点包括:
-
松散耦合:主题和观察者之间的关系是松散的,它们互不依赖,可以独立变化。
-
可复用性:可以在同一主题上注册不同的观察者,以实现不同的业务逻辑。
-
扩展性:可以随时添加新的观察者,不需要修改现有的代码。
观察者模式在实际应用中非常常见,例如在GUI开发中用于处理用户界面和数据之间的关系,事件处理机制、消息队列等。
总之,观察者模式允许对象之间建立一种松散的耦合关系,当一个对象的状态发生变化时,它可以通知多个观察者,从而实现对象间的协同工作。
2. Java实现观察者模式
2.1 以天气预报为场景
- 首先,我们定义观察者接口 Observer 和主题接口 Subject:
import java.util.List;
// 观察者接口
interface Observer {
void update(String weather);
}
// 主题接口
interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
- 接下来,创建具体的观察者 WeatherObserver 和具体的主题 WeatherStation:
import java.util.ArrayList;
import java.util.List;
// 具体观察者
class WeatherObserver implements Observer {
private String name;
public WeatherObserver(String name) {
this.name = name;
}
@Override
public void update(String weather) {
System.out.println(name + " 收到天气变化通知:" + weather);
}
}
// 具体主题
class WeatherStation implements Subject {
private List<Observer> observers = new ArrayList<>();
private String weather;
public void setWeather(String weather) {
this.weather = weather;
notifyObservers();
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(weather);
}
}
}
- 现在我们可以创建观察者并让它们订阅主题的通知:
public class Main {
public static void main(String[] args) {
WeatherStation weatherStation = new WeatherStation();
WeatherObserver observer1 = new WeatherObserver("Observer 1");
WeatherObserver observer2 = new WeatherObserver("Observer 2");
WeatherObserver observer3 = new WeatherObserver("Observer 3");
weatherStation.registerObserver(observer1);
weatherStation.registerObserver(observer2);
weatherStation.registerObserver(observer3);
weatherStation.setWeather("晴天");
weatherStation.setWeather("下雨");
}
}
当我们运行这段代码时,观察者们将会接收到主题天气变化的通知,并打印出相应的信息。这就是观察者模式的应用示例。在实际场景中,主题可以是任何需要通知观察者的对象,而观察者可以是需要订阅主题通知的各种组件或对象。
2.2 一个对象的状态变化通知多个对象:在线股票交易
- 首先,我们定义观察者接口 Observer 和主题接口 Subject:
import java.util.List;
// 观察者接口
interface Observer {
void update(String stockName, double stockPrice);
}
// 主题接口
interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
- 接下来,创建具体的观察者 StockObserver 和具体的主题 StockMarket:
import java.util.ArrayList;
import java.util.List;
// 具体观察者
class StockObserver implements Observer {
private String name;
public StockObserver(String name) {
this.name = name;
}
@Override
public void update(String stockName, double stockPrice) {
System.out.println(name + " 收到股票 " + stockName + " 的价格更新,当前价格为 " + stockPrice);
}
}
// 具体主题
class StockMarket implements Subject {
private List<Observer> observers = new ArrayList<>();
private String stockName;
private double stockPrice;
public void setStockInfo(String stockName, double stockPrice) {
this.stockName = stockName;
this.stockPrice = stockPrice;
notifyObservers();
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(stockName, stockPrice);
}
}
}
- 现在我们可以创建观察者并让它们订阅主题的通知:
public class Main {
public static void main(String[] args) {
StockMarket stockMarket = new StockMarket();
StockObserver observer1 = new StockObserver("Investor 1");
StockObserver observer2 = new StockObserver("Investor 2");
StockObserver observer3 = new StockObserver("Investor 3");
stockMarket.registerObserver(observer1);
stockMarket.registerObserver(observer2);
stockMarket.registerObserver(observer3);
stockMarket.setStockInfo("ABC", 100.0);
stockMarket.setStockInfo("XYZ", 75.5);
}
}
当股票价格发生变化时,观察者们会收到通知并打印出新的股票价格信息。这是另一个观察者模式的应用示例。观察者模式非常适合在需要解耦主题和观察者的情况下实现通知机制。