码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式之观察者模式

时间:2018-09-23 22:38:00      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:自动更新   原则   了解   src   就会   模式   业务   date   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、有多个观察者时,不可以依赖特定的通知次序。

设计模式之观察者模式

标签:自动更新   原则   了解   src   就会   模式   业务   date   com   

原文地址:https://www.cnblogs.com/Vic-S-Foever/p/Modef.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!