Источник – MSDN по .NET Framework 4.5. Шаблон разработки наблюдателя для реализации информационной системы выдачи багажа в аэропорту

Страницы работы

Фрагмент текста работы

Источник – MSDN по .NET Framework 4.5

В следующем примере шаблон разработки наблюдателя используется для реализации информационной системы выдачи багажа в аэропорту. Класс BaggageInfo предоставляет информацию о прибывающих рейсах и лентах, с которых можно получить багаж с каждого рейса. Он показан в следующем примере.

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 { et { return this.origin; }
   }
 
   public int Carousel { get { return this.location; }
   }
}

Класс BaggageHandler отвечает за получение информации о прибывающих рейсах и лентах выдачи багажа. На внутреннем уровне он поддерживает две коллекции.

·  observers - коллекция клиентов, которые будут получать обновленную информацию.

·  flights - коллекция рейсов и соответствующих им лент.

Обе коллекции представлены универсальными объектами List<T>, экземпляры которых создаются в конструкторе класса BaggageHandler. В следующем примере показан исходный код для класса BaggageHandler.

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

Клиенты, желающие получать обновленную информацию, вызывают метод BaggageInfo.Subscribe. Если клиент ранее не подписался на уведомления, ссылка на реализацию IObserver<T> клиента добавляется в коллекцию observers.

Перегруженный метод BaggageHandler.BaggageStatus может быть вызван для указания того, что багаж с определенного рейса либо выгружается, либо более не выгружается. В первом случае методу передается номер рейса, аэропорт отправления рейса и лента, на которую выгружается багаж. Во втором случае методу передается только номер рейса. Для выгружаемого багажа метод проверяет, существует ли переданная методу информация BaggageInfo в коллекции flights. Если информация не существует, метод добавляет эту информацию и вызывает метод OnNext каждого наблюдателя. В отношении рейсов, багаж которых более не выгружается, метод проверяет, хранится ли информация по этому рейсу в коллекции flights. Если информация хранится, этот метод вызывает метод OnNext каждого наблюдателя и удаляет объект BaggageInfo из коллекции flights.

После посадки последнего рейса текущего дня и обработки его багажа вызывается метод BaggageHandler.LastBaggageClaimed. Этот метод вызывает метод OnCompleted каждого наблюдателя для указания того, что все уведомления завершены, а затем очищает коллекцию observers.

Метод Subscribe поставщика возвращает реализацию IDisposable, позволяющую наблюдателям прекратить получение уведомлений до вызова метода OnCompleted. В следующем примере показан исходный код для этого класса Unsubscriber(Of BaggageInfo). Когда в методе BaggageHandler.Subscribe создается экземпляр этого класса, ему передается ссылка на коллекцию observers и ссылка на наблюдатель, добавленный в эту коллекцию. Эти ссылки назначаются локальным переменным. Когда вызывается метод Dispose объекта, он проверяет, существует ли еще наблюдатель в коллекции observers, и, если это так, удаляет наблюдатель.

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

В следующем примере приводится реализация IObserver<T> с именем ArrivalsMonitor, которая является базовым классом, отображающим информацию о выдаче багажа. Информация отображается в алфавитном порядке по названию города

Похожие материалы

Информация о работе

Тип:
Написанные программы на языках программирования
Размер файла:
73 Kb
Скачали:
0