观察程序设计模式
http://msdn.microsoft.com/zh-cn/library/Vstudio/ee850490.aspx
被观察者的接口 :IObservable<T>
观察者的接口:IObserver<T>
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Baggage { public class BaggageInfo { private int flightNo; private string origin; private int location; public BaggageInfo(int flight, string or, int loc) { flightNo = flight; origin = or; location = loc; } public int FlightNumber { get { return this.flightNo; } } public string Origin { get { return this.origin; } } public int Carousel { get { return this.location; } } } 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) { if (!observers.Contains(observer)) { observers.Add(observer); } foreach (var item in flights) { observer.OnNext(item); } return new Unsubscriber<BaggageInfo>(observers,observer); } public void BaggageStatus(int flightNo) { BaggageStatus(flightNo, String.Empty, 0); } public void BaggageStatus(int flighNo, string fro, int carousel) { var info = new BaggageInfo(flighNo,fro,carousel); if (carousel > 0 && !flights.Contains(info)) { flights.Add(info); foreach (var observer in observers) { observer.OnNext(info); } } else if(carousel==0) { var flightsToRemove = new List<BaggageInfo>(); foreach (var flight in flights) { 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(); } } 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); } } 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) { cancellation = provider.Subscribe(this); } public virtual void Unsubscribe() { cancellation.Dispose(); flightInfos.Clear(); } public virtual void OnCompleted() { Console.WriteLine("完成"); flightInfos.Clear(); } // No implementation needed: Method is not called by the BaggageHandler class. public virtual void OnError(Exception e) { Console.WriteLine("出错啦"); } // 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.Origin, 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; using System.Linq; using System.Text; namespace Baggage { class Program { static void Main(string[] args) { BaggageHandler provider = new BaggageHandler(); ArrivalsMonitor observer1 = new ArrivalsMonitor("观察者1"); ArrivalsMonitor observer2 = new ArrivalsMonitor("观察者2"); provider.BaggageStatus(712, "观察者的东西1", 3); observer1.Subscribe(provider); provider.BaggageStatus(712, "观察者的东西2", 3); provider.BaggageStatus(400, "观察者的东西3", 1); provider.BaggageStatus(712, "观察者的东西4", 3); observer2.Subscribe(provider); provider.BaggageStatus(511, "观察者的东西5", 2); provider.BaggageStatus(712); observer2.Unsubscribe(); provider.BaggageStatus(400); provider.LastBaggageClaimed(); Console.ReadKey(); } } }
浙公网安备 33010602011771号