一起来学习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);
}
}
流程简单分析
个人理解
类:
核心处理类(控制者/处理者)
信息数据列表
观察者列表
观察者类
数据信息类
释放空间
流程:
处理者接收新数据判断是否存在,不存在添加到数据列表中,然后遍历观察者列表,根据新数据执行新动作。
观察者类主要实现自身的添加和删除操作,将处理者作为参数传进自身中,调用处理者中的添加观察者函数进行添加绑定。
来源: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