Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
!Шпора по ООПиП (3).docx
Скачиваний:
35
Добавлен:
22.09.2019
Размер:
2.31 Mб
Скачать

94. Наблюдатель (шаблон проектирования)

поведенческий шаблон проектирования. Также известен как «подчинённые» (Dependents), «издатель-подписчик» (Publisher-Subscriber).

Назначение

Определяет зависимость типа «один ко многим» между объектами таким образом, что при изменении состояния одного объекта все зависящие от него оповещаются об этом событии.

Реализация

При реализации шаблона «наблюдатель» обычно используются следующие классы.

  • Observable — интерфейс, определяющий методы для добавления, удаления и оповещения наблюдателей.

  • Observer — интерфейс, с помощью которого наблюдаемый объект оповещает наблюдателей.

  • ConcreteObservable — конкретный класс, который реализует интерфейс Observable.

  • ConcreteObserver — конкретный класс, который реализует интерфейс Observer.

Область применения

Шаблон «наблюдатель» применяется в тех случаях, когда система обладает следующими свойствами:

  • существует, как минимум, один объект, рассылающий сообщения

  • имеется не менее одного получателя сообщений, причём их количество и состав могут изменяться во время работы приложения.

  • нет надобности очень сильно связывать взаимодействующие объекты, что полезно для повторного использования.

Данный шаблон часто применяют в ситуациях, в которых отправителя сообщений не интересует, что делают получатели с предоставленной им информацией.

using System;

using System.Collections;

using System.Threading;

namespace Observer

{

/// <summary>

/// Observer Pattern Judith Bishop Jan 2007

///

/// The Subject runs in a thread and changes its state

/// independently. At each change, it notifies its Observers.

/// </summary>

class Program

{

static void Main(string[] args)

{

Subject subject = new Subject();

Observer Observer = new Observer(subject,"Center","\t\t");

Observer observer2 = new Observer(subject,"Right","\t\t\t\t");

subject.Go();

// Wait for user

Console.Read();

}

}

class Simulator : IEnumerable {

string [] moves = {"5","3","1","6","7"};

public IEnumerator GetEnumerator()

{

foreach( string element in moves )

yield return element;

}

}

class Subject {

public delegate void Callback (string s);

public event Callback Notify;

Simulator simulator = new Simulator( );

const int speed = 200;

public string SubjectState { get; set; }

public void Go()

{

new Thread(new ThreadStart(Run)).Start( );

}

void Run ()

{

foreach (string s in simulator)

{

Console.WriteLine("Subject: " + s);

SubjectState = s;

Notify(s);

Thread.Sleep(speed); // milliseconds

}

}

}

interface IObserver

{

void Update(string state);

}

class Observer : IObserver

{

string name;

Subject subject;

string state;

string gap;

public Observer(Subject subject, string name, string gap)

{

this.subject = subject;

this.name = name;

this.gap = gap;

subject.Notify += Update;

}

public void Update(string subjectState)

{

state = subjectState;

Console.WriteLine(gap + name + ": " + state);

}

}

}