设计模式-观察者模式

观察者模式

一.什么是观察者模式?

   观察者模式,有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

二.观察者模式有哪些角色?

  1. 抽象主题(Subject):它把所有观察者对象的引用保存到一个聚集里(集合),每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。

    主题的功能:RegisterObserver(注册观察者),RemoveObserver(移除观察者),NotifyObservers(通知观察者)

        2. 具体主题(ConcreteSubject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。

        3.抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。

    观察者的功能:Update(更新)

        4.具体观察者(ConcreteObserver):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。

三.观察者模式的优缺点?

  优点:

    1.当被观察者状态发生改变时,会通知所有的观察者,使他们自动更新自己(广播通信);

    2.解耦,让依赖的双方都依赖抽象,而不是依赖具体实现;

  缺点:

    1.当出现循环,容易导致系统崩溃;

四.实现方式:

  1.接口: 

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading;
  6 using System.Threading.Tasks;
  7 
  8 namespace ObServer
  9 {
 10     class Program
 11     {
 12         static void Main(string[] args)
 13         {
 14             var weather = new WeatherData();
 15             var curent = new CurrentConditionDisplay();
 16             weather.RegisterObserver(curent);
 17             var curent2 = new CurrentConditionDisplay2();
 18             weather.RegisterObserver(curent2);
 19             weather.SetData(new WeatherMessage()
 20             {
 21                 Temperature = 1,
 22                 Humidity = 2,
 23                 Pressure = 3
 24             });
 25 
 26             weather.SetData(new WeatherMessage()
 27             {
 28                 Temperature = 2,
 29                 Humidity = 3,
 30                 Pressure = 4
 31             });
 32             Console.ReadKey();
 33         }
 34     }
 35 
 36     public class WeatherData : ISubject
 37     {
 38         public WeatherData()
 39         {
 40             _observerList = new List<IObserver>();
 41         }
 42         private readonly List<IObserver> _observerList;
 43         private WeatherMessage _message;
 44 
 45         public void SetData(WeatherMessage message)
 46         {
 47             _message = message;
 48             NotifyObservers();
 49         }
 50 
 51         public void NotifyObservers()
 52         {
 53             for (int i = 0; i < _observerList.Count; i++)
 54             {
 55                 var observer = _observerList[i];
 56                 observer.Update(_message);
 57             }
 58         }
 59 
 60         public void RegisterObserver(IObserver observer)
 61         {
 62             _observerList.Add(observer);
 63         }
 64 
 65         public void RemoveObserver(IObserver observer)
 66         {
 67             if (_observerList.Contains(observer))
 68             {
 69                 _observerList.Remove(observer);
 70             }
 71         }
 72     }
 73 
 74     public class CurrentConditionDisplay : IObserver
 75     {
 76         private WeatherMessage _message;
 77         
 78         public void Update(WeatherMessage message)
 79         {
 80             _message = message;
 81             Console.WriteLine($"温度:{_message.Temperature},湿度:{_message.Humidity},气压:{_message.Pressure}");
 82         }
 83     }
 84 
 85     public class CurrentConditionDisplay2 : IObserver
 86     {
 87         private WeatherMessage _message;
 88 
 89         public void Update(WeatherMessage message)
 90         {
 91             _message = message;
 92             Console.WriteLine($"温度:{_message.Temperature},湿度:{_message.Humidity},气压:{_message.Pressure}");
 93         }
 94     }
 95 
 96     /// <summary>
 97     /// 主题接口
 98     /// </summary>
 99     public interface ISubject
100     {
101         void RegisterObserver(IObserver observer);
102         void RemoveObserver(IObserver observer);
103         void NotifyObservers();
104     }
105 
106     /// <summary>
107     /// 观察者接口
108     /// </summary>
109     public interface IObserver
110     {
111         void Update(WeatherMessage message);
112     }
113 
114     public class WeatherMessage
115     {
116         /// <summary>
117         /// 温度
118         /// </summary>
119         public float Temperature { get; set; }
120 
121         /// <summary>
122         /// 湿度
123         /// </summary>
124         public float Humidity { get; set; }
125 
126         /// <summary>
127         /// 气压
128         /// </summary>
129         public float Pressure { get; set; }
130     }
131 
132 }
View Code

  2.委托 

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Data.Odbc;
  4 using System.Linq;
  5 using System.Reflection;
  6 using System.Text;
  7 using System.Threading;
  8 using System.Threading.Tasks;
  9 
 10 namespace ObServer
 11 {
 12     class Program
 13     {
 14         static void Main(string[] args)
 15         {
 16             var sub = new Subject();
 17             var ob = new Observer();
 18             sub.NotifyObservers += ob.Update;//观察者,即使没有观察者程序是不影响的(解耦)
 19             var ob2 = new Observer();
 20             sub.NotifyObservers += ob2.Update;
 21             sub.SetData(new WeatherMessage()
 22             {
 23                 Temperature = 1,
 24                 Humidity = 2,
 25                 Pressure = 3
 26             });
 27 
 28             sub.SetData(new WeatherMessage()
 29             {
 30                 Temperature = 1,
 31                 Humidity = 2,
 32                 Pressure = 3
 33             });
 34             sub.Complated();
 35             Console.ReadKey();
 36         }
 37     }
 38 
 39     public class Subject
 40     {
 41         public delegate void UpdateHandler(WeatherMessage message);
 42         public event UpdateHandler NotifyObservers;
 43         public WeatherMessage _message;
 44 
 45         public void SetData(WeatherMessage message)
 46         {
 47             _message = message;
 48             Console.WriteLine("设置数据完成");
 49             if (NotifyObservers != null)
 50             {
 51                 NotifyObservers(_message);
 52             }
 53         }
 54 
 55         public void Complated()
 56         {
 57             NotifyObservers = null;
 58             Console.WriteLine("完成");
 59         }
 60     }
 61 
 62     public class Observer
 63     {
 64         public WeatherMessage _message;
 65         public void Update(WeatherMessage message)
 66         {
 67             _message = message;
 68             Console.WriteLine($"温度:{_message.Temperature},湿度:{_message.Humidity},气压:{_message.Pressure}");
 69         }
 70     }
 71 
 72     public class Observer2
 73     {
 74         public WeatherMessage _message;
 75         public void Update(WeatherMessage message)
 76         {
 77             _message = message;
 78             Console.WriteLine($"温度:{_message.Temperature},湿度:{_message.Humidity},气压:{_message.Pressure}");
 79         }
 80     }
 81 
 82     public class WeatherMessage
 83     {
 84         /// <summary>
 85         /// 温度
 86         /// </summary>
 87         public float Temperature { get; set; }
 88 
 89         /// <summary>
 90         /// 湿度
 91         /// </summary>
 92         public float Humidity { get; set; }
 93 
 94         /// <summary>
 95         /// 气压
 96         /// </summary>
 97         public float Pressure { get; set; }
 98     }
 99 
100 }
View Code

  3.使用.net的类库:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading;
  6 using System.Threading.Tasks;
  7 
  8 namespace ObServer
  9 {
 10     class Program
 11     {
 12         static void Main(string[] args)
 13         {
 14             var weather = new Observable();
 15             var ob = new Observer();
 16             weather.Subscribe(ob);
 17             var ob2 = new Observer();
 18             weather.Subscribe(ob2);
 19             weather.SetData(new WeatherMessage()
 20             {
 21                 Temperature = 1,
 22                 Humidity = 2,
 23                 Pressure = 3
 24             });
 25             weather.SetData(new WeatherMessage()
 26             {
 27                 Temperature = 2,
 28                 Humidity = 3,
 29                 Pressure = 4
 30             });
 31             weather.Completed();
 32             Console.ReadKey();
 33         }
 34     }
 35 
 36     /// <summary>
 37     /// 主题
 38     /// </summary>
 39     public class Observable : IObservable<WeatherMessage>, IDisposable
 40     {
 41         public Observable()
 42         {
 43             _observerList = new List<IObserver<WeatherMessage>>();
 44         }
 45 
 46         private readonly List<IObserver<WeatherMessage>> _observerList;
 47         private IObserver<WeatherMessage> _observer;
 48         private WeatherMessage _message;
 49         public IDisposable Subscribe(IObserver<WeatherMessage> observer)
 50         {
 51             _observer = observer;
 52             _observerList.Add(observer);
 53             return this;
 54         }
 55 
 56         public void Dispose()
 57         {
 58             if (_observerList != null)
 59             {
 60                 _observerList.Remove(_observer);
 61             }
 62         }
 63 
 64         public void SetData(WeatherMessage message)
 65         {
 66             _message = message;
 67             foreach (var item in _observerList)
 68             {
 69                 if (_message == null)
 70                 {
 71                     item.OnError(new Exception("出差"));
 72                 }
 73                 else
 74                 {
 75                     item.OnNext(_message);
 76                     item.OnCompleted();
 77                 }
 78             }
 79         }
 80 
 81         public void Completed()
 82         {
 83             _observerList.Clear();
 84         }
 85     }
 86 
 87     /// <summary>
 88     /// 观察者
 89     /// </summary>
 90     public class Observer : IObserver<WeatherMessage>
 91     {
 92         public void OnCompleted()
 93         {
 94             Console.WriteLine("完成");
 95         }
 96 
 97         public void OnError(Exception error)
 98         {
 99             Console.WriteLine(error);
100         }
101 
102         public void OnNext(WeatherMessage value)
103         {
104             Console.WriteLine($"温度:{value.Temperature},湿度:{value.Humidity},气压:{value.Pressure}");
105         }
106     }
107 
108     /// <summary>
109     /// 观察者2
110     /// </summary>
111     public class Observer2 : IObserver<WeatherMessage>
112     {
113         public void OnCompleted()
114         {
115             Console.WriteLine("完成");
116         }
117 
118         public void OnError(Exception error)
119         {
120             Console.WriteLine(error);
121         }
122 
123         public void OnNext(WeatherMessage value)
124         {
125             Console.WriteLine($"温度:{value.Temperature},湿度:{value.Humidity},气压:{value.Pressure}");
126         }
127     }
128 
129     public class WeatherMessage
130     {
131         /// <summary>
132         /// 温度
133         /// </summary>
134         public float Temperature { get; set; }
135 
136         /// <summary>
137         /// 湿度
138         /// </summary>
139         public float Humidity { get; set; }
140 
141         /// <summary>
142         /// 气压
143         /// </summary>
144         public float Pressure { get; set; }
145     }
146 
147 }
View Code

相关推荐