观察者模式(Observer Pattern)是一种行为型设计模式,它定义了对象间的一种一对多的依赖关系,使得一个对象的状态发生改变时,所有依赖于它的对象都能够得到通知并自动更新。
在观察者模式中,有两个核心角色:Subject(主题)和Observer(观察者)。Subject(主题)维护一组观察者对象,当它的状态发生改变时,会通知所有的观察者对象。而Observer(观察者)则定义了一个接口,用于接收主题通知时的回调函数。
下面是一个简单的观察者模式Demo,假设有一个天气主题,它维护了一组观察者(天气预报员),当天气发生改变时,会通知所有的观察者对象:
python
Copy
# 主题抽象类
class Subject:
def register_observer(self, observer):
pass
def remove_observer(self, observer):
pass
def notify_observers(self):
pass
# 观察者抽象类
class Observer:
def update(self, temperature, humidity, pressure):
pass
# 天气主题类
class WeatherData(Subject):
def __init__(self):
self.observers = []
self.temperature = None
self.humidity = None
self.pressure = None
def register_observer(self, observer):
self.observers.append(observer)
def remove_observer(self, observer):
self.observers.remove(observer)
def notify_observers(self):
for observer in self.observers:
observer.update(self.temperature, self.humidity, self.pressure)
def set_measurements(self, temperature, humidity, pressure):
self.temperature = temperature
self.humidity = humidity
self.pressure = pressure
self.measurements_changed()
def measurements_changed(self):
self.notify_observers()
# 天气预报员类
class WeatherObserver(Observer):
def update(self, temperature, humidity, pressure):
print(f"温度:{temperature},湿度:{humidity},气压:{pressure}")
# 客户端代码
weather_data = WeatherData()
observer1 = WeatherObserver()
observer2 = WeatherObserver()
weather_data.register_observer(observer1)
weather_data.register_observer(observer2)
weather_data.set_measurements(30, 70, 101.3)
# 输出:
# 温度:30,湿度:70,气压:101.3
weather_data.remove_observer(observer2)
weather_data.set_measurements(28, 80, 100.5)
# 输出:
# 温度:28,湿度:80,气压:100.5
在这个Demo中,WeatherData是主题类,它维护了一组观察者对象,并实现了注册、删除和通知观察者的方法。WeatherObserver是观察者类,它实现了更新方法,用于接收主题通知时的回调函数。
当客户端使用观察者模式时,需要先定义一个主题抽象类和观察者抽象类,然后实现具体的主题类和观察者类。主题类维护了观察者列表,并实现了通知观察者的方法。观察者类实现了更新方法,用于接收主题通知时的回调函数。
观察者模式的应用场景比较广泛,例如:
消息订阅系统:用户可以订阅感兴趣的消息主题,当该主题有新消息时,系统会自动通知所有订阅者。
GUI框架:用户界面中的控件可以作为观察者,当模型层的数据发生改变时,控件会自动更新显示。
股票行情系统:投资者可以订阅自己关注的股票行情,当该股票价格发生变化时,系统会自动通知所有订阅者。
补充一下,这个示例是Python代码,下面是一个相似的Java代码示例:
java
Copy
import java.util.*;
// 主题抽象类
interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
// 观察者抽象类
interface Observer {
void update(float temperature, float humidity, float pressure);
}
// 天气主题类
class WeatherData implements Subject {
private List<Observer> observers;
private float temperature;
private float humidity;
private float pressure;
public WeatherData() {
observers = new ArrayList<>();
}
public void registerObserver(Observer observer) {
observers.add(observer);
}
public void removeObserver(Observer observer) {
observers.remove(observer);
}
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(temperature, humidity, pressure);
}
}
public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
public void measurementsChanged() {
notifyObservers();
}
}
// 天气预报员类
class WeatherObserver implements Observer {
public void update(float temperature, float humidity, float pressure) {
System.out.println("温度:" + temperature + ",湿度:" + humidity + ",气压:" + pressure);
}
}
// 客户端代码
WeatherData weatherData = new WeatherData();
Observer observer1 = new WeatherObserver();
Observer observer2 = new WeatherObserver();
weatherData.registerObserver(observer1);
weatherData.registerObserver(observer2);
weatherData.setMeasurements(30, 70, 101.3f);
// 输出:
// 温度:30.0,湿度:70.0,气压:101.3
weatherData.removeObserver(observer2);
weatherData.setMeasurements(28, 80, 100.5f);
// 输出:
// 温度:28.0,湿度:80.0,气压:100.5
这个Java示例与Python示例类似,只是语言不同。
以下是一些推荐的学习资料和链接,可以帮助你更好地学习观察者模式:
《Head First 设计模式》:这是一本非常通俗易懂的设计模式入门书籍,其中包含了对观察者模式的讲解和示例代码。
《设计模式:可复用面向对象软件的基础》:这是设计模式的经典著作之一,其中包含了对观察者模式的详细讲解和示例代码。
《图解设计模式:以UML为基础,学习23种设计模式》:这是一本以图解为主的设计模式入门书籍,其中包含了对观察者模式的详细讲解和示例代码。
观察者模式的Java实现:这是一个包含了观察者模式示例代码的Java项目,可以帮助读者更好地理解和应用观察者模式。
GitHub链接:https://github.com/iluwatar/java-design-patterns/tree/master/observer ↗
总之,学习观察者模式需要结合书籍和实践,建议读者选择一些适合自己的入门书籍,同时结合实际项目中的设计问题进行实践,加深对观察者模式的理解和应用。