设计模式之观察者模式
Posted vic-s-foever
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式之观察者模式相关的知识,希望对你有一定的参考价值。
认识观察者模式可以通过报纸和杂志的订阅了解原理:
1、报社的业务就是出版报纸
2、向某家报社订阅报纸,只要他们有新报纸出版,就会给你送来。只要你是他们的订户,你就会一直收到新报纸。
3、当你不想再看报纸的时候,取消订阅,他们就不会再送新报纸来。
4、只要报社还在运营,就会一直有人(或单位)向他们订阅报纸或者取消订阅报纸。
了解上面报纸和杂志的订阅过程,其实就能了解观察者模式是怎么一回事,其中出版者在模式中称为主题,订阅者在模式中称为观察者。
观察者模式
定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新,这种对象设计让主题和观察者之间松耦合(松耦合作为设计原则之一能让我们建立有弹性的OO系统,能够应对变化,是因为对象之间的互相依赖降到了最低)
简单程序片段
public interface ISubject { void registerObserver(IObserver o); void removeObserver(IObserver o); void notifyObservers(); } /// <summary> /// 主题对应观察者需要实现的接口 /// </summary> public interface IObserver { void update(float temp, float humidity, float pressure); } /// <summary> /// 观察者其他接口 /// </summary> public interface IDisplayElement { void display(); } public class WeatherData : ISubject { private ArrayList observers; private float temperature; private float humidity; private float pressure; public WeatherData() { observers = new ArrayList(); } /// <summary> /// 注册观察者 /// </summary> /// <param name="o"></param> public void registerObserver(IObserver o) { observers.Add(o); } /// <summary> /// 移除观察者 /// </summary> /// <param name="o"></param> public void removeObserver(IObserver o) { int i = observers.IndexOf(o); if (i >= 0) { observers.Remove(o); } } /// <summary> /// 通知观察者 /// </summary> public void notifyObservers() { foreach (var item in observers) { IObserver observer = (IObserver)item; observer.update(temperature, humidity, pressure); } } /// <summary> /// 数据更新通知观察者 /// </summary> public void measurementsChanged() { notifyObservers(); } /// <summary> /// 模拟接收数据 /// </summary> /// <param name="temperature"></param> /// <param name="humidity"></param> /// <param name="pressure"></param> public void setMeasurements(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; measurementsChanged(); } } /// <summary> /// 观察者1 /// </summary> public class CurrentConditionsDisplay : IObserver, IDisplayElement { private float temperature; private float humidity; private ISubject weatherData; public CurrentConditionsDisplay(ISubject 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() { Console.WriteLine("Current conditions: " + temperature + "F degrees and" + humidity + "% humidity"); } } /// <summary> /// 观察者2 /// </summary> public class StatisticsDisplay : IObserver, IDisplayElement { private float temperature; private float humidity; private ISubject weatherData; public StatisticsDisplay(ISubject 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() { Console.WriteLine("statisti conditions: " + temperature + "F degrees and" + humidity + "% humidity"); } } /// <summary> /// 观察者3 /// </summary> public class ForacastDisplay : IObserver, IDisplayElement { private float temperature; private float humidity; private ISubject weatherData; public ForacastDisplay(ISubject 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() { Console.WriteLine("forecast conditions: " + temperature + "F degrees and" + humidity + "% humidity"); } }
测试程序
static void Main(string[] args) { WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentconditionsdisplay = new CurrentConditionsDisplay(weatherData); StatisticsDisplay statsticsdisplay = new StatisticsDisplay(weatherData); ForacastDisplay foracastdisplay = new ForacastDisplay(weatherData); weatherData.setMeasurements(80, 65, 30.4f); weatherData.removeObserver(currentconditionsdisplay); weatherData.removeObserver(statsticsdisplay); weatherData.setMeasurements(82, 70, 29.2f); weatherData.registerObserver(statsticsdisplay); weatherData.setMeasurements(78, 90, 29.2f); Console.Read(); }
观察者模式注意要点:
1、观察者模式定义了对象之间的一对多的关系。
2、主题(可观察者)用一个共同的接口来更新观察者
3、观察者和主题之间用松耦合方式结合,可观察者不知道观察者的细节,只知道观察者实现了观察者接口。
4、有多个观察者时,不可以依赖特定的通知次序。
以上是关于设计模式之观察者模式的主要内容,如果未能解决你的问题,请参考以下文章