第二章 觀察者模式1

觀察者模式

觀察者模式定義了對象之間的一對多的依賴,這樣一來,當一個對象的狀態改變時,它的所有依賴者都會收到通知並且自動更新。

實現方法

觀察的對象爲可觀察者,要被通知的對象稱爲觀察者。
觀察者都實現同一個接口,裏面有一個方法用來被可觀察者調用,實現通知的功能。可觀察者實現可被觀察的接口,在觀察者中調用可觀察者接口的方法實現註冊,刪除觀察者等功能。

代碼

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 觀察者模式
{
    class Program
    {
        static void Main(string[] args)
        {
            WeatherData weatherData=new WeatherData();

            CurrentConditionsDisplay currentDisplay=new CurrentConditionsDisplay(weatherData);
            StatisticsDisplay statisticsDisplay=new StatisticsDisplay(weatherData);
            ForecastDisplay forecastDisplay=new ForecastDisplay(weatherData);

            // 虛擬數據
            weatherData.SetMeasurements(80,65,30.4f);
            weatherData.SetMeasurements(82, 70, 29.2f);
            weatherData.SetMeasurements(78, 90, 29.2f);

            Console.ReadKey();
        }
    }


    // 觀察者接口
    public interface IObserver
    {
        // 更新數據方法
        void Update(float temp,float humidity,float pressure);
    }

    // 觀察者目標接口
    public interface ISubject
    {
        // 註冊觀察者方法
        void RegisterObserver(IObserver o);
        // 移除觀察者方法
        void RemoveObserver(IObserver o);
        // 通知方法
        void NotifyObservers();
    }

    // 顯示接口
    public interface IDisplayElement
    {
        // 顯示方法
        void Display();
    }

    // 觀察者的具體目標,實現目標接口
    public class WeatherData:ISubject
    {
        private List<IObserver> _observers; // 觀察者列表
        private float _temprature;
        private float _humidity;
        private float _pressure;

        public WeatherData()
        {
            _observers=new List<IObserver>();
        }

        // 註冊觀察者
        public void RegisterObserver(IObserver o)
        {
            _observers.Add(o);
        }

        // 移除觀察者
        public void RemoveObserver(IObserver o)
        {
            if (_observers.Contains(o))
            {
                _observers.Remove(o);
            }
        }

        // 通知觀察者值改變,通過調用觀察者列表中實現觀察者接口的函數
        public void NotifyObservers()
        {
            foreach (var observer in _observers)
            {
                observer.Update(_temprature,_humidity,_pressure);
            }
        }

        // 通知觀察者值發生改變
        public void MeasurementsChanged()
        {
           NotifyObservers();
        }

        // 獲取實時值並且通知值改變
        public void SetMeasurements(float temperature, float humidity, float pressure)
        {
            _temprature = temperature;
            _humidity = humidity;
            _pressure = pressure;
            MeasurementsChanged();
        }

        // WeatherData 的其它方法
    }

    // 具體的觀察者
    public class CurrentConditionsDisplay:IObserver,IDisplayElement
    {
        private float _temprature;
        private float _humidity;
        private ISubject _weatherData;

        // 實例化時傳入觀察目標實例的接口
        public CurrentConditionsDisplay(ISubject weatherData)
        {
            _weatherData = weatherData;
            _weatherData.RegisterObserver(this);
        }

        // 通過接口方法獲得數據
        public void Update(float temp, float humidity, float pressure)
        {
            _temprature = temp;
            _humidity = humidity;
            Display();
        }

        public void Display()
        {
            Console.WriteLine($"Current conditions: {_temprature}F degrees and {_humidity}% humidity");
        }
    }

    public class ForecastDisplay : IObserver, IDisplayElement
    {
        private float _temprature;
        private float _humidity;
        private ISubject _weatherData;

        public ForecastDisplay(ISubject weatherData)
        {
            _weatherData = weatherData;
            _weatherData.RegisterObserver(this);
        }

        public void Update(float temp, float humidity, float pressure)
        {
            _temprature = temp;
            _humidity = humidity;
            Display();
        }

        public void Display()
        {
            Console.WriteLine($"Forecast: {_temprature}F degrees and {_humidity}% humidity");
        }
    }

    public class ThirdPartyDisplay : IObserver, IDisplayElement
    {
        private float _temprature;
        private float _humidity;
        private ISubject _weatherData;

        public ThirdPartyDisplay(ISubject weatherData)
        {
            _weatherData = weatherData;
            _weatherData.RegisterObserver(this);
        }

        public void Update(float temp, float humidity, float pressure)
        {
            _temprature = temp;
            _humidity = humidity;
            Display();
        }

        public void Display()
        {
            Console.WriteLine($"ThirdParty: {_temprature}F degrees and {_humidity}% humidity");
        }
    }

    public class StatisticsDisplay : IObserver, IDisplayElement
    {
        private float _temprature;
        private float _humidity;
        private ISubject _weatherData;

        public StatisticsDisplay(ISubject weatherData)
        {
            _weatherData = weatherData;
            _weatherData.RegisterObserver(this);
        }

        public void Update(float temp, float humidity, float pressure)
        {
            _temprature = temp;
            _humidity = humidity;
            Display();
        }

        public void Display()
        {
            Console.WriteLine($"Statistics: {_temprature}F degrees and {_humidity}% humidity");
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章