【发布时间】:2013-12-30 23:37:47
【问题描述】:
我正在阅读(很棒的)书Head First Design Patterns,需要对观察者模式进行一些澄清。下面的一小段代码模拟了一个设备 (CurrentConditionDisplay),它监听天气模式的更新。
接口:
public interface ISubject
{
void RegisterObserver(IObserver obs);
void RemoveObserver(IObserver obs);
void NotifyObservers();
}
public interface IDisplay
{
string Display();
}
public interface IObserver
{
void Update(float temperature, float humidity, float pressure);
}
观察者
public class CurrentConditionDisplay : IObserver, IDisplay
{
private float temperature;
private float humidity;
private float pressure;
private ISubject weatherData;
public CurrentConditionDisplay(ISubject weatherData)
{
this.weatherData = weatherData;
this.weatherData.RegisterObserver(this);
}
public string Display()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("Welcome to Current Condition Display...");
sb.AppendLine(this.temperature.ToString());
sb.AppendLine(this.humidity.ToString());
sb.AppendLine(this.pressure.ToString());
return sb.ToString();
}
public void Update(float temperature, float humidity, float pressure)
{
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
}
}
主题
public class WeatherData : ISubject
{
private List<IObserver> observersList;
private float temperature;
private float humidity;
private float pressure;
public WeatherData()
{
observersList = new List<IObserver>();
}
public void RegisterObserver(IObserver obs)
{
observersList.Add(obs);
}
public void RemoveObserver(IObserver obs)
{
int index = observersList.IndexOf(obs);
if (index >= 0)
{
observersList.RemoveAt(index);
}
}
public void MeasurementsChanged()
{
Console.WriteLine("There is new data available...");
NotifyObservers();
}
public void NotifyObservers()
{
foreach (IObserver observer in observersList)
{
observer.Update(temperature, humidity, pressure);
}
}
public void SetMeasurements(float temperature, float humidity, float pressure)
{
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
MeasurementsChanged();
}
}
为了在我的 Program.cs 中使用这些类,我创建了一次 WeatherData 的实例并将该对象作为参数传递给 CurrentConditionDisplay 的构造函数。我在当前设置中看到的一个问题是IObserver 有一个方法Update,它将temperature, humidity, pressure 作为参数。我认为不能保证主题(WeatherData)必须首先拥有这些字段。我是否应该添加另一个接口或抽象基类以确保在调用SetMeasurements时,该方法中正在更新的所有字段实际上都在Observer中?
【问题讨论】:
-
仅供参考,C# 内置了观察者模式的实现。见Events
-
你说的'是什么意思'确保在那个方法中被更新的所有字段实际上都在观察者中'?读了好几遍了,还是不明白你的问题
-
@JohnSaunders 那是一本关于设计模式的书。目标是理解观察者的想法,而不是学习 C# 特性)
-
@lazyberezovsky 我的意思是没有什么让
WeatherData拥有temperature, humidity, pressure作为私有字段。 Observer 和 Subject 没有通用接口(共享那些更新的字段)。 -
@wootscootinboogie 我又听不懂你了——温度、湿度和压力是天气数据的私有字段。为什么你说没有把它们作为私有领域?
标签: c# design-patterns observer-pattern