意图/定义(intent)
(简短的描述该模式的作用。)
观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖着都会收到通知并自动更新。
问题/动机(motivation)
(动机给出来问题以及如何解决这个问题的具体场景。)
气象站应用:建立一个应用,利用WeatherData对象取得数据,并更新三个布告板:目前状况,气象统计和天机预报。
- WeatherData类可以获得三个测量值:温度、湿度与气压。
- 当新的测量值数据备妥时,changed() 方法就会被调用。
- 我们需要实现三个布告板,一旦WeatherData有新的测量,这些布告板必须马上更新。
- 此系统必须可扩展,让其他开发人员建立定制的布告板,用户可以随心所欲的添加或删除任何布告板。
适用性(applicability)
(适用性描述模式可以被应用在什么场合。)
- 当一个对象状态的改变需要改变其他对象;或实际对象是事先未知的或动态变化的。
-
结构(structure)
参与者(participants)
(参与者描述在此设计中所涉及到的类和对象在模式中的责任和角色。)
协作(collaborations)
优点
开闭原则:你无须修改发布者类就能引入新的订阅者。
-
缺点
-
实现/范例代码(implementation/sample code)
(实现提供了你在实现该模式时需要使用的技巧,以及你应该小心面对的问题。)
(范例代码提供代码的片段,可能对你的实现有多帮助。) ```dart /// 观察者模式实现气象观测站代码
/// observer.dart 文件 /// 观察者接口 abstract class Observer { // 当主题状态改变时调用 void update(double temperature, double humidity, double pressure); }
/// subject.dart 文件 /// 主题接口 import ‘./observer.dart’;
abstract class Subject { // 注册观察者 void registerObserver(Observer observer); // 删除观察者 void removeObserver(Observer observer); // 通知观察者 void notifyObserver(); }
/// display_element.dart 文件 /// 布告板接口 abstract class DisplayElement { void display(); }
/// weather_data.dart 文件 /// 气象站观测数据类,实现主题接口 import ‘./subject.dart’; import ‘./observer.dart’;
class WeatherData implements Subject { List _observers; // 观察者 double _temperature; // 温度 double _humidity; // 湿度 double _pressure; // 压强
WeatherData() { _observers = new List(); }
@override void registerObserver(Observer observer) { this._observers.add(observer); }
@override void removeObserver(Observer observer) { this._observers.remove(observer); }
@override void notifyObserver() { _observers.forEach((element) { element.update(_temperature, _humidity, _pressure); }); }
// 测量数据发生变化时调用此函数 void measurementsChanged() { this.notifyObserver(); }
// 设置测量值,测试使用方法 void setMeasurements(double temperature, double humidity, double pressure) { this._temperature = temperature; this._humidity = humidity; this._pressure = pressure;
this.measurementsChanged();
} }
/// current_conditions_display.dart 文件 /// 当前天气布告板 import ‘./observer.dart’; import ‘./display_element.dart’; import ‘./weather_data.dart’;
class CurrentConditionsDisplay implements Observer, DisplayElement { WeatherData _weatherData; double _temperature; double _humidity;
CurrentConditionsDisplay(WeatherData weatherData) { _weatherData = weatherData; _weatherData.registerObserver(this); }
@override void update(double temperature, double humidity, double pressure) { _temperature = temperature; _humidity = humidity;
display();
}
@override void display() { print(‘温度:${_temperature};湿度:${_humidity}’); } }
/// forecast_display.dart 文件 /// 天气预报预告版 import ‘./observer.dart’; import ‘./display_element.dart’; import ‘./weather_data.dart’;
class ForecastDisplay implements Observer, DisplayElement { WeatherData _weatherData; double _pressure;
ForecastDisplay(WeatherData weatherData) { _weatherData = weatherData; _weatherData.registerObserver(this); }
@override void update(double temperature, double humidity, double pressure) { _pressure = pressure;
display();
}
@override void display() { print(‘气压:${_pressure}’); } }
/// statistics_display.dat 文件 /// 统计布告板 import ‘./observer.dart’; import ‘./display_element.dart’; import ‘./weather_data.dart’;
class StatisticsDisplay implements Observer, DisplayElement { WeatherData _weatherData; double _temperature; double _humidity; double _pressure;
StatisticsDisplay(WeatherData weatherData) { _weatherData = weatherData; _weatherData.registerObserver(this); }
@override void update(double temperature, double humidity, double pressure) { _temperature = temperature; _humidity = humidity; _pressure = pressure;
display();
}
@override void display() { print(‘温度:${_temperature};湿度:${_humidity};气压:${_pressure}’); } }
/// test.dart 文件 /// 气象监测应用测试代码 import ‘./weather_data.dart’; import ‘./current_conditions_display.dart’; import ‘./forecast_display.dart’; import ‘./statistics_display.dart’;
void main() { WeatherData weatherData = WeatherData(); CurrentConditionsDisplay currentConditionsDisplay = CurrentConditionsDisplay(weatherData); ForecastDisplay forecastDisplay = ForecastDisplay(weatherData); StatisticsDisplay statisticsDisplay = StatisticsDisplay(weatherData);
weatherData.setMeasurements(80, 65, 30.4); weatherData.setMeasurements(60, 55, 20.6); weatherData.setMeasurements(100, 75, 40.8); }
已知应用(known uses)
相关模式(related patterns)
(相关模式描述了此模式和其他模式之间的关系。)
- 责任链:按照顺序将请求动态的传递给一系列的潜在接受者,直至其中一名接受者对请求进行处理。
- 命令:在发送者和请求者之间建立单项链接。
- 中介:清除了发送者和请求者之间的直接连接,强制他们通过一个中介对象进行间接沟通。
-
OO知识
OO基础
抽象
- 封装
- 多态
- 继承
OO原则