背景来自《Head First设计模式》
背景:客户是一家气象研究所,他们提供一个气象数据接口,开发者可以通过这个接口获得气象数据二次开发。
数据包括三个(分别以三个数据面板显示)
气象研究所提供的源代码
1 /// <summary>
2 /// Weather Data
3 /// </summary>
4 class WeatherDatacs
5 {
6 double getTemperature();
7 double getHumidity();
8 double getPressure();
9
10 void measurementsChanged();
11 }
一个错误的例子
void measurementsChanged() { //气象数据发生变化 float temp = getTemperature(); float humidity = getHumidity(); float pressure = getPressure(); //更新面板 currentConditionDisplay.update(temp, humidity, pressure); statisticsDisplay.update(temp, humidity, pressure); forecastDisplay.update(temp, humidity, pressure); }
错误点:
1.面向实现编程,没有面向接口
2.对于每个新的布告板,我们都需要修改代码
3.我们无法动态的删除、增加布告板
4.布告板没有实现一个共同的接口 update
观察者模式
定义了对象之间一对多的依赖,这样一来,当一个对象状态改变时,他的所有依赖者都会收到通知并自动更新。
被依赖的对象称为 主题 Subject
依赖者称为 观察者 Observer
主题接口
/// <summary> /// Subject Interface /// /// </summary> interface ISubject { //注册观察对象 当有新的观察者提出加入请求时 void registerObserver(); //删除观察对象 解除依赖关系 void removeObserver(); //状态改变时, 通知观察者 void notifyObserver(); }
观察者接口
/// <summary> /// 观察者 接口 /// </summary> interface IObserver { void update(); }
具体实现
/// <summary> /// Weather Data /// </summary> class WeatherDatacs : ISubject { ArrayList observerList; private float temperature; private float humidity; private float pressure; public WeatherDatacs() { observerList = new ArrayList(); } //实现ISubject 接口 //面向接口编程 public void registerObserver(IObserver o) { observerList.Add(o); } public void removeObserver(IObserver o) { int i = observerList.IndexOf(o); if(i >= 0) { observerList.Remove(o); } } public void notifyObserver() { for (int i = 0; i < observerList.Count; i++ ) { IObserver observer = (IObserver)observerList[i]; observer.update(temperature, humidity, pressure); } } void measurementsChanged() { notifyObserver(); } public void setMeasurements(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; measurementsChanged(); } }
//Observer 部分
class CurrentConditionDisplay : IObserver, IDisplayment { //主题对象 WeatherDatacs weatherData; float temperature; float humidity; public CurrentConditionDisplay(ISubject weatherData) { this.weatherData = (WeatherDatacs)weatherData; weatherData.registerObserver(this); } public void update(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; display(); } //实现 Display public void display() { Console.WriteLine("Current conditions: {0} F degrees and {1}% humidity", this.temperature, this.humidity); } }
打印测试
static void Main(string[] args) { //测试 WeatherDatacs weatherData = new WeatherDatacs(); CurrentConditionDisplay currentDisplay = new CurrentConditionDisplay(weatherData); weatherData.setMeasurements(100, 90, 100); weatherData.setMeasurements(2, 1, 3); weatherData.setMeasurements(4, 12, 323); weatherData.setMeasurements(321, 123, 3234); weatherData.setMeasurements(312, 312, 321); }
原文:http://www.cnblogs.com/timeglass/p/4368366.html