今天看到了HeadFirst DesignPattern 的第二章,Observer观察者模式:在对象之间定义一对多的依赖,这样依赖,当一个对象改变状态,依赖它的对象就会受到通知,并自动更新。并且还提到了设计这个观察者模式的OO原则:为交互对象之间的松耦合设计而努力。以下是学习观察者模式的要点:
1、观察者模式定义了对象之间一对多的关系。
2、主题(观可察者)用一个共同的接口来更新观察者。
3、观察者和主题之间用松耦合方式结合,主题不知道观察者的细节,只知道观察者实现了观察者接口。
4、有多个观察者时,不可以依赖特定的通知顺序。
我用C#改写的代码贴在下面:
using System;
using System.Collections.Generic;
using System.Text;

namespace Strategy


{

观察者模式的接口#region 观察者模式的接口

/**//// <summary>
/// 主题接口,用来唯一维护整个局部系统的状态值
/// </summary>
public interface Subject

{
//注册和删除观察者的方法
void registerObserver(Observer o);
void removeObserver(Observer o);
//当主题状态改变时,这个方法会被调用,以通知所有的观察者
void notifyObserver();
}

/**//// <summary>
/// 观察者接口
/// </summary>
public interface Observer

{
//当主题状态改变时会把这些状态值当作参数,传递给观察者。
void update(float temp, float humidity, float pressure);
}

/**//// <summary>
/// 具体到这个设计,观察者要实现的另外一个外观接口
/// </summary>
public interface DisplayElement

{
void display();
}
#endregion



具体实现类#region 具体实现类

/**//// <summary>
/// 主题的实现类
/// </summary>
public class WeatherData : Subject

{
//添加了一个泛型List来记录观察者
private List<Observer> observers;
private float temperature;
private float humidity;
private float pressure;

public WeatherData()

{
observers = new List<Observer>();
}

//接口中的方法实现
public void registerObserver(Observer o)

{
observers.Add(o);
}
public void removeObserver(Observer o)

{
if(observers.Contains(o))

{
observers.Remove(o);
}
}
//把状态的改变告诉每一个观察者。
public void notifyObserver()

{
foreach (Observer o in observers)

{
o.update(temperature, humidity, pressure);
}
}
//当从气象站得到新观察值的时候,我们通知观察者
public void measurementsChanged()

{
notifyObserver();
}
//利用这个方法来测试布告版,唉,气象站的数据还送给我们啊
public void setMeasurements(float temperature, float humidity, float pressure)

{
this.temperature = temperature;
this.humidity = humidity;
this.pressure =pressure;
//嗨,注意了,天气情况有变化了,通知一下各位布告版更改一下它们的数据
measurementsChanged();
}
}



/**//// <summary>
/// 实现其中一个布告版本,别的雷同省略
/// </summary>
public class CurrentCoditionsDisplay : Observer, DisplayElement

{
private float temperature;
private float humidity;
private Subject weatherData;
//在构造函数中为这个观察者进行注册
public CurrentCoditionsDisplay(Subject weatherData)

{
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
public void update(float temperature, float humidity, float pressure)

{
this.temperature = temperature;
this.humidity = humidity;
display();
}
public void display()

{
System.Console.WriteLine("Current conditions:"+temperature+"F degrees and "+humidity+" %humidity");
System.Console.ReadLine();
}
}
#endregion


测试类#region 测试类
public class WeatherStation

{
public static void Main(string[] args)

{
WeatherData weatherData = new WeatherData();

//暂时只实现了一个观察者,这里就注册这一个观察者吧
CurrentCoditionsDisplay currentDisplay =
new CurrentCoditionsDisplay(weatherData);
weatherData.setMeasurements(80f, 65f, 34.1f);
}
}
#endregion
}
