一起來(lái)學(xué)習(xí)C#的觀察者模式
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");
// 添加信息,此時(shí)沒(méi)有觀察者,對(duì)于新的信息不會(huì)進(jìn)行操作,若有觀察者,則對(duì)觀察者內(nèi)部數(shù)據(jù)進(jìn)行對(duì)比,若有新內(nèi)容則進(jìn)行更新。
provider.BaggageStatus(712, "Detroit", 3);
// 添加了觀察者,觀察者內(nèi)部也有數(shù)據(jù)集。新信息傳進(jìn)來(lái),會(huì)與內(nèi)部數(shù)據(jù)集進(jìn)行對(duì)比,若有新內(nèi)容則進(jìn)行更新。
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);
//參數(shù)3為0 執(zhí)行移除712對(duì)應(yīng)信息值,對(duì)應(yīng)觀察者打印
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)
{
// 參數(shù)是處理者! 添加觀察者 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);
}
}
流程簡(jiǎn)單分析


個(gè)人理解
類:
- 核心處理類(控制者/處理者)
- 信息數(shù)據(jù)列表
- 觀察者列表
- 觀察者類
- 數(shù)據(jù)信息類
- 釋放空間
流程:
處理者接收新數(shù)據(jù)判斷是否存在,不存在添加到數(shù)據(jù)列表中,然后遍歷觀察者列表,根據(jù)新數(shù)據(jù)執(zhí)行新動(dòng)作。
觀察者類主要實(shí)現(xiàn)自身的添加和刪除操作,將處理者作為參數(shù)傳進(jìn)自身中,調(diào)用處理者中的添加觀察者函數(shù)進(jìn)行添加綁定。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
C#中的modbus Tcp協(xié)議的數(shù)據(jù)抓取和使用解析
這篇文章主要介紹了C#中的modbus Tcp協(xié)議的數(shù)據(jù)抓取和使用解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
C#?TaskScheduler任務(wù)調(diào)度器的實(shí)現(xiàn)
本文主要介紹了C#?TaskScheduler任務(wù)調(diào)度器的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧<BR>2023-05-05
利用C#實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲(chóng)
這篇文章主要介紹了利用C#實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲(chóng),完整的介紹了C#實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲(chóng)詳細(xì)過(guò)程,感興趣的小伙伴們可以參考一下2016-03-03
C#實(shí)現(xiàn)主窗體最小化后出現(xiàn)懸浮框及雙擊懸浮框恢復(fù)原窗體的方法
這篇文章主要介紹了C#實(shí)現(xiàn)主窗體最小化后出現(xiàn)懸浮框及雙擊懸浮框恢復(fù)原窗體的方法,涉及C#窗體及鼠標(biāo)事件響應(yīng)的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08
C#實(shí)現(xiàn)多線程的Web代理服務(wù)器實(shí)例
這篇文章主要介紹了C#實(shí)現(xiàn)多線程的Web代理服務(wù)器,涉及C#多線程代理服務(wù)器的實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07
C#實(shí)例化和靜態(tài)類對(duì)象調(diào)用對(duì)比
這篇文章主要介紹了C#實(shí)例化和靜態(tài)類對(duì)象調(diào)用對(duì)比,什么時(shí)候用實(shí)例化對(duì)象,什么時(shí)候用靜態(tài)類對(duì)象,內(nèi)存和生命周期又是如何,框架本身的回收機(jī)制是什么,下文詳細(xì)解說(shuō)需要的小伙伴可以參考一下2022-04-04
VS2015為console.readkey添加代碼片段的方法
這篇文章主要介紹了VS2015為console.readkey添加代碼片段的方法,需要的朋友可以參考下2016-12-12

