一起来学习C#的观察者模式

作者:ou.cs 时间:2022-04-02 13:43:15 

using System;
using System.Collections.Generic;
public class Example
{
   public static void Main()
   {
       BaggageHandler provider = new BaggageHandler();
       ArrivalsMonitor observer1 = new ArrivalsMonitor("BaggageClaimMonitor1");
       ArrivalsMonitor observer2 = new ArrivalsMonitor("SecurityExit");
       // 添加信息,此时没有观察者,对于新的信息不会进行操作,若有观察者,则对观察者内部数据进行对比,若有新内容则进行更新。
       provider.BaggageStatus(712, "Detroit", 3);
       // 添加了观察者,观察者内部也有数据集。新信息传进来,会与内部数据集进行对比,若有新内容则进行更新。
       observer1.Subscribe(provider);
       provider.BaggageStatus(712, "Kalamazoo", 3);
       provider.BaggageStatus(400, "New York-Kennedy", 1);
       provider.BaggageStatus(712, "Detroit", 3);
       observer2.Subscribe(provider);
       provider.BaggageStatus(511, "San Francisco", 2);
       //参数3为0 执行移除712对应信息值,对应观察者打印
       provider.BaggageStatus(712);
       observer2.Unsubscribe();
       provider.BaggageStatus(400);
       provider.LastBaggageClaimed();
   }
}
// The example displays the following output:
//      Arrivals information from BaggageClaimMonitor1
//      Detroit                712    3
//
//      Arrivals information from BaggageClaimMonitor1
//      Detroit                712    3
//      Kalamazoo              712    3
//
//      Arrivals information from BaggageClaimMonitor1
//      Detroit                712    3
//      Kalamazoo              712    3
//      New York-Kennedy       400    1
//
//      Arrivals information from SecurityExit
//      Detroit                712    3
//
//      Arrivals information from SecurityExit
//      Detroit                712    3
//      Kalamazoo              712    3
//
//      Arrivals information from SecurityExit
//      Detroit                712    3
//      Kalamazoo              712    3
//      New York-Kennedy       400    1
//
//      Arrivals information from BaggageClaimMonitor1
//      Detroit                712    3
//      Kalamazoo              712    3
//      New York-Kennedy       400    1
//      San Francisco          511    2
//
//      Arrivals information from SecurityExit
//      Detroit                712    3
//      Kalamazoo              712    3
//      New York-Kennedy       400    1
//      San Francisco          511    2
//
//      Arrivals information from BaggageClaimMonitor1
//      New York-Kennedy       400    1
//      San Francisco          511    2
//
//      Arrivals information from SecurityExit
//      New York-Kennedy       400    1
//      San Francisco          511    2
//
//      Arrivals information from BaggageClaimMonitor1
//      San Francisco          511    2
using System;
using System.Collections.Generic;
public class ArrivalsMonitor : IObserver<BaggageInfo>
{
   private string name;
   private List<string> flightInfos = new List<string>();
   private IDisposable cancellation;
   private string fmt = "{0,-20} {1,5}  {2, 3}";
   public ArrivalsMonitor(string name)
   {
       if (String.IsNullOrEmpty(name))
           throw new ArgumentNullException("The observer must be assigned a name.");
       this.name = name;
   }
   public virtual void Subscribe(BaggageHandler provider)
   {
                     // 参数是处理者! 添加观察者 this
       cancellation = provider.Subscribe(this);
   }
   public virtual void Unsubscribe()
   {
       cancellation.Dispose();
       flightInfos.Clear();
   }
   public virtual void OnCompleted()
   {
       flightInfos.Clear();
   }
   // No implementation needed: Method is not called by the BaggageHandler class.
   public virtual void OnError(Exception e)
   {
       // No implementation.
   }
   // Update information.
   public virtual void OnNext(BaggageInfo info)
   {
       bool updated = false;
       // Flight has unloaded its baggage; remove from the monitor.
       if (info.Carousel == 0)
       {
           var flightsToRemove = new List<string>();
           string flightNo = String.Format("{0,5}", info.FlightNumber);
           foreach (var flightInfo in flightInfos)
           {
               if (flightInfo.Substring(21, 5).Equals(flightNo))
               {
                   flightsToRemove.Add(flightInfo);
                   updated = true;
               }
           }
           foreach (var flightToRemove in flightsToRemove)
               flightInfos.Remove(flightToRemove);
           flightsToRemove.Clear();
       }
       else
       {
           // Add flight if it does not exist in the collection.
           string flightInfo = String.Format(fmt, info.From, info.FlightNumber, info.Carousel);
           if (!flightInfos.Contains(flightInfo))
           {
               flightInfos.Add(flightInfo);
               updated = true;
           }
       }
       if (updated)
       {
           flightInfos.Sort();
           Console.WriteLine("Arrivals information from {0}", this.name);
           foreach (var flightInfo in flightInfos)
               Console.WriteLine(flightInfo);
           Console.WriteLine();
       }
   }
}
using System;
using System.Collections.Generic;
public class BaggageHandler : IObservable<BaggageInfo>
{
   private List<IObserver<BaggageInfo>> observers;
   private List<BaggageInfo> flights;
   public BaggageHandler()
   {
       observers = new List<IObserver<BaggageInfo>>();
       flights = new List<BaggageInfo>();
   }
   public IDisposable Subscribe(IObserver<BaggageInfo> observer)
   {
       // Check whether observer is already registered. If not, add it
       if (!observers.Contains(observer))
       {
           observers.Add(observer);
           // Provide observer with existing data.
           foreach (var item in flights)
               observer.OnNext(item);
       }
       return new Unsubscriber<BaggageInfo>(observers, observer);
   }
   // Called to indicate all baggage is now unloaded.
   public void BaggageStatus(int flightNo)
   {
       BaggageStatus(flightNo, String.Empty, 0);
   }
   public void BaggageStatus(int flightNo, string from, int carousel)
   {
       var info = new BaggageInfo(flightNo, from, carousel);
       // Carousel is assigned, so add new info object to list.
       if (carousel > 0 && !flights.Contains(info))
       {
           flights.Add(info);
           foreach (var observer in observers)
               observer.OnNext(info);
       }
       else if (carousel == 0)
       {
           // Baggage claim for flight is done
           var flightsToRemove = new List<BaggageInfo>();
           foreach (var flight in flights)
           {
               if (info.FlightNumber == flight.FlightNumber)
               {
                   flightsToRemove.Add(flight);
                   foreach (var observer in observers)
                       observer.OnNext(info);
               }
           }
           foreach (var flightToRemove in flightsToRemove)
               flights.Remove(flightToRemove);
           flightsToRemove.Clear();
       }
   }
   public void LastBaggageClaimed()
   {
       foreach (var observer in observers)
           observer.OnCompleted();
       observers.Clear();
   }
}
using System;
using System.Collections.Generic;
public class BaggageInfo
{
   private int flightNo;
   private string origin;
   private int location;
   internal BaggageInfo(int flight, string from, int carousel)
   {
       this.flightNo = flight;
       this.origin = from;
       this.location = carousel;
   }
   public int FlightNumber
   {
       get { return this.flightNo; }
   }
   public string From
   {
       get { return this.origin; }
   }
   public int Carousel
   {
       get { return this.location; }
   }
}
using System;
using System.Collections.Generic;
internal class Unsubscriber<BaggageInfo> : IDisposable
{
   private List<IObserver<BaggageInfo>> _observers;
   private IObserver<BaggageInfo> _observer;
   internal Unsubscriber(List<IObserver<BaggageInfo>> observers, IObserver<BaggageInfo> observer)
   {
       this._observers = observers;
       this._observer = observer;
   }
   public void Dispose()
   {
       if (_observers.Contains(_observer))
           _observers.Remove(_observer);
   }
}

流程简单分析

一起来学习C#的观察者模式

一起来学习C#的观察者模式

个人理解

类:

  • 核心处理类(控制者/处理者)

    • 信息数据列表

    • 观察者列表

  • 观察者类

  • 数据信息类

  • 释放空间

流程:

处理者接收新数据判断是否存在,不存在添加到数据列表中,然后遍历观察者列表,根据新数据执行新动作。

观察者类主要实现自身的添加和删除操作,将处理者作为参数传进自身中,调用处理者中的添加观察者函数进行添加绑定。

来源:https://blog.csdn.net/weixin_44291381/article/details/123655797

标签:C#,观察者,模式
0
投稿

猜你喜欢

  • C#读取系统字体颜色与大小的方法

    2021-12-29 07:54:57
  • C#实现时间戳与标准时间的互转

    2023-07-16 08:09:38
  • C++常见错误中英文对照表

    2023-06-05 04:52:13
  • C#实现简单聊天程序的方法

    2022-01-02 22:31:20
  • C#操作txt文件,进行清空添加操作的小例子

    2023-05-24 14:06:07
  • SpringCloud可视化链路追踪系统Zipkin部署过程

    2023-11-27 04:34:06
  • Java毕业设计实战之健身器材商城系统的实现

    2022-12-18 01:39:56
  • Jmeter非GUI模式运行分布式测试

    2021-11-08 12:42:07
  • java增强for循环的实现方法

    2023-12-07 16:42:53
  • Android仿拉手网团购App我的收藏界面实例代码

    2023-11-18 18:31:38
  • C#中Lambda表达式的三种写法

    2022-03-27 02:50:27
  • java后台实现支付宝对账功能的示例代码

    2021-10-29 22:15:29
  • SpringBoot借助spring.factories文件跨模块实例化Bean

    2021-12-01 18:22:41
  • C++选择排序算法实例

    2021-10-27 21:43:33
  • 解决IDEA中maven导入jar包一直报错问题

    2021-12-26 11:52:22
  • 详解Java中的ThreadLocal

    2022-08-19 17:48:43
  • 在Linux上运行C#的方法

    2023-03-06 00:28:39
  • springboot项目中jackson-序列化-处理 NULL教程

    2022-11-03 14:36:21
  • Spring中Bean的加载与SpringBoot的初始化流程详解

    2022-12-18 05:02:18
  • mybatis 实现多层级collection嵌套

    2022-07-19 21:33:18
  • asp之家 软件编程 m.aspxhome.com