观察程序设计模式

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();

        }
    }
}

 

posted on 2012-12-06 10:39  R.Ray  阅读(145)  评论(0)    收藏  举报

导航