zoukankan      html  css  js  c++  java
  • 设计模式-观察者模式

    观察者模式

    一.什么是观察者模式?

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

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

      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
  • 相关阅读:
    OpenStack-Ocata版+CentOS7.6 云平台环境搭建 — 2.安装配置OpenStack基础服务
    OpenStack-Ocata版+CentOS7.6 云平台环境搭建 — 1.操作系统环境配置
    ssh免密登录
    PHP实现识别带emoji表情的字符串
    算法-PHP实现八大算法
    项目总结-第一次外包项目2-项目相关
    PHP.52-TP框架商城应用实例-前台4-商品详情页-面包屑导航、AJAX浏览历史
    PHP.51-TP框架商城应用实例-前台3-楼层推荐、TP框架雪崩问题
    PHP.50-TP框架商城应用实例-前台2-商品推荐
    PHP.49-TP框架商城应用实例-前台1-公共布局、制作首页
  • 原文地址:https://www.cnblogs.com/zlp520/p/13862200.html
Copyright © 2011-2022 走看看