学习设计模式之旅 / 观察者模式 (Observers)

        观察者模式(Observers)  定义了对象之间的一对多依赖,这个一来,当一个对象改变状态时,它所有的依赖者都会收到通知并自动更新,主题和观察者定义了一对多的关系 观察者依赖于主题,只要主题状态一有改变,观察者就会接受到通知 根据通知的风格;
       当两个对象之间松耦合,它们依然可以交互,但不太清除彼此的细节。观察者模式提供了一种对象设计,让主题和观察者之间松耦合。主题只知道观察者实现了某个接口(也就是Observer接口)主题不需要知道观察者的具体类是谁,做了些什么或其他的任何细节。任何时候我们可以添加新的观察者。因为主题唯一依赖的东西是一个实现Observer接口的对象列表。
      松耦合的设计之所以能让我们建立有弹性的OO系统,能够应对变化,是因为对象之间的互相依赖降到了最低。所以我们 为了交互对象之间的松耦合设计而在努力。
Demo - 气象监测应用系统
     气象观测局专利申请在WeatherData对象中,由WeatherData负责追踪天气状态。成功以后以供布告板显示,由可能很多不同的布告板,每个布告板的显示都有所不同,并且当Weather对象得到新的数据时,所有布告板都必须更新。
 
namespace Exercise.BureauOfMeteorologyBackup
{
     /// <summary>
     /// 主题的接口
     /// </summary>
     interface ISubject
    {
         /// <summary>
         ///  登记观测者
         /// </summary>
         /// <param name="o"></param>
         void RegisterObserver(IObserver o);

         /// <summary>
         ///  移除观察者
         /// </summary>
         /// <param name="o"></param>
         void RemoveObserver(IObserver o);

         /// <summary>
         ///  通知观察着
         /// </summary>
         /// <!--  
         ///     当主题状态改变时这个方法会被调用 以通知所有的观察者 -->
         void NotifyObservers();
    }

     class WeatherData : ISubject
    {

         /// <summary>
         /// <!-- 使用ArrayList的形式来记录观察者 -->
         /// </summary>
         private ArrayList observers;

         private float temperature;

         private float humidity;

         private float pressure;

         public WeatherData(){
            observers = new ArrayList();
        }

ISubject 成员 #region ISubject 成员

         /// <summary>
         ///  当注册观察者时 只需要添加到ArrayList后面即可
         /// </summary>
         /// <param name="o"></param>
         public void RegisterObserver(IObserver o)
        {
            observers.Add(o);
        }

         /// <summary>
         /// 当取消注册的时只需要从ArrayList移除即可
         /// </summary>
         /// <param name="o"></param>
         public void RemoveObserver(IObserver o)
        {
             int i = observers.IndexOf(o);

             if (i >= 0){
                observers.Remove(i);
            }
        }

         /// <summary>
         /// 通知所有观察者新的状态  
         /// </summary>
         public void NotifyObservers()
        {
             for ( int i = 0; i < observers.Count; i++){

                IObserver observer = (IObserver)observers[i];

                observer.Update(temperature, humidity, pressure);

            }
        }

        #endregion

         /// <summary>
         ///  当从气象局得到更新观测值时 通知所有观察者
         /// </summary>
         public void MeasurementsChanged(){
            NotifyObservers();
        }

         public void SetMeasurements( float temperature, float humidity, float pressure)
        {
            Console.WriteLine( "Began to inform all observers ..");

             this.temperature = temperature;

             this.humidity = humidity;

             this.pressure = pressure;

            MeasurementsChanged();  

            Console.WriteLine( "End to all observers ..");
        }
    }
}


namespace Exercise.BureauOfMeteorologyBackup
{
     /// <summary>
     /// <!-- 所有的气象局组件都实现此观察者接口 主题在需要通知观察者时 有一个共同的接口 -->
     /// </summary>
     interface IObserver
    {
         /// <summary>
         ///  <!-- 当气象局观测值改变时 主题会把这些状态值当作方法的参数 传递给观察者 -->
         /// </summary>
         void Update( float temperature, float humidity, float pressure);
    }

     interface IDisplayElement
    {
         /// <summary>
         ///  当布告板需要显示时 调用此方法
         /// </summary>
         void Display();
    }
}

namespace Exercise.BureauOfMeteorologyBackup.Display
{
     class CurrentConditions: IObserver ,IDisplayElement
    {
         private float temperature;

         private float humidity;

         private ISubject weatherData;

         public CurrentConditions(ISubject weatherData)
        {
             this.weatherData = weatherData;

            weatherData.RegisterObserver( this);
        }

IDisplayElement 成员 #region IDisplayElement 成员

         /// <summary>
         ///  显示最近的温度和湿度
         /// </summary>
         public void Display()
        {
            Console.WriteLine(
                 "Current conditions : " + temperature +
                     "  F degrees and " + humidity + "% humidity");
        }

        #endregion

IObserver 成员 #region IObserver 成员

         /// <summary>
         ///  温度和湿度保存然后显示
         /// </summary>
         public void Update( float temperature, float humidity, float pressure)
        {
             this.temperature = temperature;

             this.humidity = humidity;

            Display();
        }

        #endregion
    }
}
namespace Exercise.BureauOfMeteorologyBackup.Display
{
     class Forecast:IObserver,IDisplayElement
    {
         private float temperature;

         private float humidity;

         private WeatherData weatherData;

         public Forecast(WeatherData weatherData)
        {
             this.weatherData = weatherData;
            weatherData.RegisterObserver( this);
        }

IObserver 成员 #region IObserver 成员

         public void Update( float temperature, float humidity, float pressure)
        {
             this.temperature = temperature;

             this.humidity = humidity;
            
            Display();
        }

        #endregion

IDisplayElement 成员 #region IDisplayElement 成员

         public void Display()
        {
            Console.WriteLine(
                 "Forecast : " + temperature +
                     "  F degrees and " + humidity + "% humidity");
        }

        #endregion
    }
}

你可能感兴趣的:(设计模式,观察者模式,观察者,observer,休闲)