zoukankan      html  css  js  c++  java
  • C#设计模式之3:观察者模式

    C#中已经实现了观察者模式,那就是事件,事件封装了委托,使得委托的封装性更好,在类的内部定义事件,然后在客户端对事件进行注册:

     public class Subject
        {
            public event Action<int> MyEvent;
            public async Task ExecuteEvent()
            {
                for (int i = 0; i < 100; i++)
                {
                    await Task.Delay(TimeSpan.FromSeconds(0.1));
                    Console.Write(".");
                    if (i>50)
                    {
                        MyEvent(i);
                        return;
                    }
                }            
            }
    
        }
     class Program
        {
            static void Main(string[] args)
            {
                Subject sub = new Subject();
                sub.MyEvent += (a) =>
                {
                    Console.WriteLine($"the temprature is {a} now ,please shutdown!");              
                };
                Task task= sub.ExecuteEvent();          
                Console.ReadKey();
            }
        }

    可以说在C#中实现观察者模式是非常方便的。

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

    上面的例子可能比较简单,Subject类充当的就是一个主题,或者叫发布者,使用+=注册的lambda充当的就是一个订阅者,也就是Observer,(lambda表达式会生成一个匿名的类,更准确的说实际上这个匿名的类就是一个Observer)将会有很多的类似于这样的订阅者来对Subject的MyEvent事件进行注册,所以Subject和Observer是一对多的。当我们执行Subject中的ExecuteEvent方法时,就是在满足一定条件后发出通知,而Observer就会去执行相应的动作,这就是观察者模式。因为这个模式涉及到了对象和对象之间的依赖,这么这里又涉及到一个概念,那就是耦合。

    设计原则:为了交互对象之间的松耦合而努力。

    手动实现的观察者模式(java)

    还是以headfirst设计模式这本书上的例子为依据,这个例子讲的是一个气象站(ISubject)和很多布告板(Observer)的故事,先上类图:

     观察者模式中有两个角色,一个是Subject,主题角色,这个角色用来发布消息,另一个是Observer,观察者,用来接收消息。Subject和Observer的关系是一对多。

     /// <summary>
        /// 定义一个主题对象的接口,主题对象可以发出通知。
        /// 被观察者(IObserver)接受并做出相应的动作。
        /// 主题对象和观察者之间是一对多的关系。
        /// </summary>
        public interface ISubject
        {
            void RegisterObserver(IObserver observer);
            void RemoveObserver(IObserver observer);
            void NotifyObservers();
        }
    
        public interface IObserver
        {
            void Update(float temp, float humidity, float pressure);
        }
    
        public interface IDisplay
        {
            void Display();
        }
        /// <summary>
        /// ConcreteSubject角色
        /// </summary>
        public class WeatherData:ISubject
        {
            private readonly IList<IObserver> _observers=new List<IObserver>();
            public float Temp { get; set; }
            public float Humidity { get; set; }
            public float Pressure { get; set; }
            public void RegisterObserver(IObserver observer)
            {
               _observers.Add(observer);
            }
    
            public void RemoveObserver(IObserver observer)
            {
                _observers.Remove(observer);
            }
    
            public void NotifyObservers()
            {
                foreach (IObserver item in _observers)
                {
                   item.Update(Temp,Humidity,Pressure);
                }
            }
    
    
            public void SetMeasurements(float temp, float humidity, float pressure)
            {
                Temp = temp;
                Humidity = humidity;
                Pressure = pressure;
                NotifyObservers();            
            }
        }
        public class CurrentConditionDisplay:IObserver,IDisplay
        {
            private float _temperature;
            private float _humidity;
            private ISubject _weatherData;
            public CurrentConditionDisplay(ISubject weatherData)
            {
                _weatherData = weatherData;
                _weatherData.RegisterObserver(this);
            }
            public void Update(float temperature, float humidity, float pressure)
            {
                _temperature = temperature;
                _humidity = humidity;
                Display();
            }
            public void Display()
            {
                Console.WriteLine($"out temperature is {_temperature},out humidity is {_humidity}");
            }
           
        }
  • 相关阅读:
    正则入门小随
    用栈求简单算术表达式的值
    数据结构复习
    数据结构笔记(第九章)
    数据结构笔记(第八章)
    Java第三阶段学习(十四、JSP动态页面、EL表达式、JSTL标签库)
    Java第三阶段学习(十三、会话技术、Cookie技术与Session技术)
    Java第三阶段学习(十二、HttpServletRequest与HttpServletResponse)
    Java第三阶段学习(十一、Servlet基础、servlet中的方法、servlet的配置、ServletContext对象)
    Java第三阶段学习(十、XML学习)
  • 原文地址:https://www.cnblogs.com/pangjianxin/p/7978289.html
Copyright © 2011-2022 走看看