观察者模式是一种常见的设计模式,用于构建对象间的一对多依赖关系,当被观察者对象发生状态变化时,所有依赖于它的观察者对象都将自动接收到变化通知,并进行相应的处理操作。本文将从多个角度分析观察者模式的UML图。
1. 模式结构
观察者模式包含三个基本角色:Subject(主题)、Observer(观察者)和ConcreteObserver(具体观察者)。其中,Subject是被观察者对象,它具有一个状态,当状态发生改变时,会通知所有的观察者对象;Observer是观察者对象,它定义了一个更新接口,当被观察者对象通知变化时,观察者对象将进行更新操作;ConcreteObserver是具体的观察者对象,它实现了Observer接口,并定义了自己的更新行为。
观察者模式的UML图如下所示:

2. 模式应用
观察者模式所有的实现均是基于Subject与Observer之间的一对多关系,这种关系对于场景模型的实现有很大的优势。例如,在图形用户界面(GUI)开发中,控件之间的交互通常就是通过观察者模式来实现的,一个控件的变化会通知其他控件进行相应的更新操作。在电商网站中,购物车也是通过观察者模式来实现的,当用户添加或删除商品时,购物车会自动更新。
3. 模式优缺点
观察者模式有如下优点:
(1)一个Subject对象可以被多个Observer对象观察,降低了对象之间的耦合度。
(2)新增或删除观察者对象都非常方便,只需要增加或删除观察者即可。
(3)Subject和Observer之间的关系基于抽象,有利于扩展模型的实现。
观察者模式也有如下缺点:
(1)Observer对象与Subject对象之间的依赖关系可能导致循环调用,造成程序运行效率低下。
(2)当Observer对象数量较多时,一次状态变化可能会引起大量的Observer对象更新,极大地影响程序性能。
(3)Observer对象之间可能存在层次性的依赖关系,从而产生复杂性。
4. 模式实例
一个简单的观察者模式实例是模拟气象站,当气象数据发生变化时,三个不同的观测者(当前状况布告、统计布告和预测布告)将会接收到相应的通知。在这个实例中,WeatherData是被观察者对象(Subject),CurrentConditionsDisplay、StatisticsDisplay和ForecastDisplay是观察者对象(Observer),它们都实现了Observer接口,具体代码实现可以参考如下:
```java
public interface Observer {
public void update(float temp, float humidity, float pressure);
}
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}
public class WeatherData implements Subject {
private ArrayList
private float temperature;
private float humidity;
private float pressure;
public WeatherData() {
observers = new ArrayList<>();
}
public void registerObserver(Observer o) {
observers.add(o);
}
public void removeObserver(Observer o) {
int i = observers.indexOf(o);
if (i >= 0) {
observers.remove(i);
}
}
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(temperature, humidity, pressure);
}
}
public void measurementsChanged() {
notifyObservers();
}
public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
}
public class CurrentConditionsDisplay implements Observer {
private float temperature;
private float humidity;
public void display() {
System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity");
}
public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
display();
}
}
public class StatisticsDisplay implements Observer {
private float temperature;
private float humidity;
public void display() {
System.out.println("Statistics: " + temperature + "F degrees and " + humidity + "% humidity");
}
public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
display();
}
}
public class ForecastDisplay implements Observer {
private float temperature;
private float humidity;
public void display() {
System.out.println("Forecast: " + temperature + "F degrees and " + humidity + "% humidity");
}
public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
display();
}
}
public class Main {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay();
StatisticsDisplay statisticsDisplay = new StatisticsDisplay();
ForecastDisplay forecastDisplay = new ForecastDisplay();
weatherData.registerObserver(currentDisplay);
weatherData.registerObserver(statisticsDisplay);
weatherData.registerObserver(forecastDisplay);
weatherData.setMeasurements(80, 65, 30.4f);
weatherData.setMeasurements(82, 70, 29.2f);
weatherData.setMeasurements(78, 90, 29.2f);
}
}
```
5.
扫码咨询 领取资料