设计模式之观察者模式

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、有多个观察者时,不可以依赖特定的通知次序。

以上是关于设计模式之观察者模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式 行为型模式 -- 观察者模式(发布-订阅(Publish/Subscribe)模式)

js设计模式之实现观察者模式实例代码

PHP设计模式之----观察者模式

PHP 设计模式之观察者模式

设计模式之观察者模式--PHP

设计模式之观察者模式2