模式学习---观察者模式

  有这么一个项目,气象局发布温度,湿度,空气压力等数据,分别在不同的地方显示。这样的情况适合用观察者模式,观察者模式变化的是观察者,观察者数量不固定,所以要封装观察者。 把观察者设计成一个接口
public interface IObserver
    {
        void Update(double temperature, double humidity, double pressure);
    }
为方便显示,再设计一个显示接口
public interface IDisplayElement
    {
        void Display();
    }
主题接口设计成这样
 public interface ISubject
    {
        IList<WeatherTest.IObserver> Observers { get; set; }

        void Register(IObserver observer);
        void Remove(IObserver observer);
        void NotifyObservers();
    }
currentconditions继承观察者接口
 public class CurrentConditions : IObserver,IDisplayElement
    {
        private double _temperature;
        private double _humidity;
        private double _pressure;
        public void Display()
        {
            Console.WriteLine($"当前环境:温度{_temperature}  湿度{_humidity}");
        }

        public void Update(double temperature, double humidity, double pressure)
        {
            _temperature = temperature;
            _humidity = humidity;
            _pressure = pressure;
            Display();
        }
    }
Forecast也继承观察者接口
  public class Forecast : IObserver,IDisplayElement
    {
        private double _temperature;
        private double _humidity;
        private double _pressure;
        public void Display()
        {
            Console.WriteLine($"天气预报:明天温度{_temperature}  明天湿度{_humidity}");
        }

        public void Update(double temperature, double humidity, double pressure)
        {
            _temperature = temperature;
            _humidity = humidity;
            Display();
        }
    }
WeatherData从主题接口继承,为代码实现起来表现更优雅一些,重载了运算符+和-
 public class WeatherData : ISubject
    {
        private IList<IObserver> observers;
        private double _temperature;
        private double _humidity;
        private double _pressure;
        public IList<IObserver> Observers { get => observers; set => observers = value; }

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

        public void NotifyObservers()
        {
            foreach(IObserver o in Observers)
            {
                o.Update(_temperature, _humidity, _pressure);
            }
        }

        public void Register(IObserver observer)
        {
            Observers.Add(observer);
        }

        public void Remove(IObserver observer)
        {
            Observers.Remove(observer);
        }

        public static WeatherData operator +(WeatherData lhs,IObserver rhs)
        {
            lhs.Register(rhs);
            return lhs;
        }

        public static WeatherData operator -(WeatherData lhs,IObserver rhs)
        {
            lhs.Remove(rhs);
            return lhs;
        }

        public void SetMeasurements(double temperature,double humidity,double pressure)
        {
            _temperature = temperature;
            _humidity = humidity;
            _pressure = pressure;
            NotifyObservers();
        }
    }
现在可以实现看看
static void Main(string[] args)
        {
            WeatherData weather = new WeatherData();
            CurrentConditions current = new CurrentConditions();
            Forecast forecast = new Forecast();
            Console.WriteLine($"=====================>关联观察者");
            weather += current;
            weather += forecast;
            Console.WriteLine($"=====================>设置温湿度");
            weather.SetMeasurements(23, 35, 20);
            Console.WriteLine($"=====================>移去一个当前环境观察者");
            weather -= current;
            weather.SetMeasurements(20, 20, 20);
            Console.WriteLine($"=====================>运行结束");
            Console.ReadLine();
        }

结果如图显示,设计是成功的。


用C#的事件也可以实现观察者模式,把WeatherData封装成继承EventArgs的类,也很简单。




阅读更多
上一篇模式学习---策略模式
下一篇模式学习---用C#内置接口实现观察者模式
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭