HeadFirst设计模式(2)-观察者模式(ObserverPattern)

第二节观察者模式(OberverPattern)

HeadFirst这节给出的案例是气象站监测应用系统。背景是:气象站通过物流装置获取气象信息,生成WeatherData(气象数据),最后通过布告板显示给用户。WeatherData可以获取物理装置的数据,并且将数据显示到布告板上:目前状况(温度、湿度、气压)、气象统计和天气预报。

先给出一个错误示范

 public class WeatherData
    {
        public float GetTemperature()
        {
            return 25;
        }
        public float GetHumidity()
        {
            return 60;
        }

        public float GetPressure()
        {
            return 1;
        }

        public void MeasurementsChanged(){
            float temp = GetTemperature();
            float humidity = GetHumidity();
            float pressure = GetPressure();

            CurrentConditionsDisplay.Update(temp, humidity, pressure);
            StatisticsDisplay.Update(temp, humidity, pressure);
            ForecasDisplay.Update(temp, humidity, pressure);
        }
    }

这个代码示例中在更新布告板的时候,有两个问题:1、因为更新布告板都是调用了Update()方法,且参数都相同,这就违背了上一张策略模式中,需要将改变的地方封装起来。2、现在的布告板都是针对现实编程,如果要增加或删除布告板时就不要修改代码。

我们先不急于解决这些问题,先了解一下观察者模式(Observer)。

定义:观察者模式定义了对象之间一对多依赖,这样依赖,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

对象通过主题接口注册为观察者或把自己从观察者中删除。一个具体的主题来实现主题接口。

利用观察者模式主题和观察者实现了之间的松耦合。使之直接可以交互,但是不清楚彼此的细节。

这里应用了一个设计原则--为交互对象之间的松耦合设计而努力

松耦合的设计之所以能让我们建立有弹性的OO系统,能够对应变化,是因为对象之间的互相依赖降到了最低。

回到气象站的问题,我们用观察者模式来设计气象站系统,如下图所示类图。

这样我们来实现这些代码

气象站的接口及实现类

    public interface IWeatherData
    {
        /// <summary>
        /// 注册成为观察者
        /// </summary>
        /// <param name="o"></param>
        void RegisterObserver(IObserver o);
        /// <summary>
        /// 取消观察者
        /// </summary>
        /// <param name="o"></param>
        void RemoveObserver(IObserver o);
        /// <summary>
        /// 当数据更新是调用
        /// </summary>
        void NotifyObserver();
    }

 public class WeatherData:IWeatherData {
        private ArrayList Observers;
        private float temperature;
        private float humidity;
        private float pressure;
        public WeatherData()
        {
            this.Observers = new ArrayList();
        }
        public void RegisterObserver(IObserver o) {
            this.Observers.Add(o);
        }
        public void RemoveObserver(IObserver o)
        {
            this.Observers.Remove(o);
        }
        public void NotifyObserver()
        {
            foreach (IObserver item in Observers)
            {
                item.Update(this.temperature,this.humidity,this.pressure);
            }
        }

        public void MeasurementsChanged()
        {
            NotifyObserver();
        }

        public void SetMeasurements(float temp, float humidity, float pressure)
        {
            this.temperature = temp;
            this.humidity = humidity;
            this.pressure = pressure;
            MeasurementsChanged();
        }
    }

布告板的接口及实现类

   public interface IObserver
    {
        void Update(float temp, float humidity, float pressure);
    }

   public interface IDisplayElement
    {
        void Display();
    }

 public class CurrentConditionsDisplay:IObserver,IDisplayElement
    {
        private float temperature;
        private float humidity;
        private float pressure;
        public IWeatherData weatherData;
        public CurrentConditionsDisplay(IWeatherData weatherData)
        {
            this.weatherData = weatherData;
            weatherData.RegisterObserver(this);
        }
        public  void Update(float temp, float humidity, float pressure)
        {
            this.temperature = temp;
            this.humidity = humidity;
            this.pressure = pressure;
            Display();
        }

        public void Display()
        {
            Console.WriteLine(string.Format("气压版显示 温度:{0},湿度:{1}",this.temperature,this.humidity));
        }
    }

这样准备工作就做完了,开始执行

 WeatherData weatherData = new WeatherData();
            CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);

            weatherData.SetMeasurements(80, 65, 30.4f);

同理,我们再将其他的观察者同样处理,修改完成后,在执行语句里面添加定义即可

WeatherData weatherData = new WeatherData();
            CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
            StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);

            weatherData.SetMeasurements(80, 65, 30.4f);

OK执行结果达到了需求。

通过学习我们知道,当我们后面再要添加新的观察者或者要去掉以前的观察者时,不需要对WeatherData进行任何编辑,只需要把观察者的接口进行实现,并且在调用的时候注册即可。这样系统就非常有弹性。

时间: 2024-08-25 02:21:53

HeadFirst设计模式(2)-观察者模式(ObserverPattern)的相关文章

【C++实现】HeadFirst设计模式之观察者模式

观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新. 一方可称为主题(subject),另一方可称为观察者(observer),一个主题可拥有多个观察者.当主题的数据有变动时,就会通知所有订阅了它的观察者.在这之后的操作有两种: 推:主题直接将数据推送给所有观察者. 拉:主题通知了所有观察者后,每个观察者再根据自己的需要从主题拉取所需数据. 下面是我用C++实现的代码,其中的update方法采用了"拉"的方式从主题获取数据. //

Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---观察者模式之WeatherReport[转]

  1  2{<HeadFirst设计模式>之观察者模式 }  3{ 主题与观察者                    }  4{ 编译工具 :Delphi7.0            }  5{ 联系方式 :[email protected]    }  6  7unit uWeatherReport;  8  9interface 10 11uses 12  Classes, SysUtils; 13 14type 15  TObserver = class; { Forward声明,创

【HeadFirst设计模式——开篇】

最近在看HeadFirst,接下来的一段时间会陆续更新有关HeadFirst设计模式相关的文章.记得很久之前在学习大话设计模式的时候,只是走马观花的大致走过一遍,至于里面很多东西都掌握的不是很好.恰巧又接触了HeadFirst,想着还是把设计模式好好的整理一下,至于是大话设计还是HeadFirst,个人看来是无关紧要的.本着学习的目的,而且都是设计模式,只不过一个是C#,一个是Java. 本来第一篇文章想着从观察者模式开始讲起,但是想着想着,还是把UML的类图的关系捋一下吧,不然的话类图都看不懂

Headfirst设计模式的C++实现——策略模式(Strategy)

前言 最近在学习<Headfirst设计模式>,里面的例子都是Java的.但是我对Java并不熟悉,所以试着用C++来实现书中的例子. 先来看看Duck以及子类 Duck.h 1 #include <iostream> 2 #include "FlyBehavior.h" 3 4 class Duck 5 { 6 private: 7 FlyBehavior *m_p_fly_behavior; 8 public: 9 virtual void quack()

【设计模式】观察者模式

生活中,当某件事发生时,应该通知所有的相关者.例如,上课地点有变,要通知所有学习这门课的同学. 在软件设计中,当一个对象的状态发生变化是,如何通知与它相关的所有对象,就是我们今天要谈到的观察者模式. 观察者模式 概述 定义了一种一对多的依赖关系.让多个观察者对象同事监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有的观察者对象,使它们能够自动更新自己. 实际上,观察者模式所做的工作就是在解除耦合.让耦合的双方都依赖于抽象,而不是依赖于具体.从而使得各自的变化都不会影响另一边的变化. 结

设计模式:观察者模式

设计模式:观察者模式 : http://www.cnblogs.com/li-peng/archive/2013/02/04/2892116.html 观察者模式是我们经常用的一个模式,比如在用wcf做服务的时候通知客户端做一些操作一般用设计者模式. 今天做一个订报纸的小例子来理解一下观察者模式  出版者+订阅者=观察者模式 用下边的图来说就是    人民日报+订阅者=观察者模式 只要是订阅了人民日报的人,有了新报纸就会送到订阅者那里去, 当你不想订的时候取消就不订阅就不会再收到报纸了. //报

设计模式之-观察者模式

该文代码来自设计模式之惮一书. 观察者模式定义: 观察者模式也叫做发布订阅模式. 观察者模式中的角色: 1.被观察者 被观察者职责为管理观察者并通知观察者. 2.观察者 对接受到的消息进行处理. /// <summary> /// 被观察者 /// </summary> public abstract class Subject { /// <summary> /// 观察者集合 /// </summary> private List<IObserva

设计模式(16) 观察者模式(OBSERVER)C++实现

意图: 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 动机: 将一个系统设计成一系列相互协作的类有一个常见的副作用:需要维护相关对象之间的一致性. 观察者模式定义一种交互,即发布-订阅: 一个对象当自身状态发生改变时,会发出通知,但是并不知道谁是他的接收者,但每个接收者都会接收到通知,这些接受者称为观察者. 作为对通知的响应,每个观察者都将查询目标状态,然后改变自身的状态以和目标状态进行同步. 使用场景: 使对象封装为独立的改变和使用:

&lt;&lt;Head First设计模式&gt;&gt;之观察者模式学习

1.概念 定义了对象之间的一对多依赖关系,当一个对象(主题对象)的状态改变时,它的所有依赖者(观察者对象)都会收到通知并自动更新. 2.优势 观察者模式实现了主题对象与观察者对象之间的松耦合,当有新的观察者时,无需修改主题对象的代码,只需要新的观察者对象实现接口.在程序运行的过程中,可以随时注册和删除观察者而不影响主体对象. 观察者模式使主题(Subject)对象和观察者(Observer)对象都可以被轻易地复用. 3.Java中观察者模式 Java API有内置的观察者模式,java.util