Читайте также:
|
|
ClockTimer - это конкретный субъект, который следит за временем суток. Он извещает наблюдателей каждую секунду. Класс ClockTimer предоставляет
интерфейс для получения отдельных компонентов времени: часа, минуты, секунды и т.д.:
class ClockTimer: public Subject { public:
ClockTimer();
virtual int GetfHour ();
virtual int GetMinute(); virtual int GetSecond (');
void Tick();
Операция Tick вызывается через одинаковые интервалы внутренним таймером. Тем самым обеспечивается правильный отсчет времени. При этом обновляется внутреннее состояние объекта ClockTimer и вызывается операция Noti fy для извещения наблюдателей об изменении:
void ClockTimer::Tick () {
// обновить внутреннее представление о времени
Notify ();
Теперь мы можем определить класс DigitalClock, который отображает время. Свою графическую функциональность он наследует от класса Widget, предоставляемого библиотекой для построения пользовательских интерфейсов. Интерфейс наблюдателя подмешивается к интерфейсу DigitalClock путем наследования от класса Observer:
class DigitalClock: public Widget, public Observer { public:
DigitalClock(ClockTimer*);
virtual -DigitalClock();
virtual void Update(Subject*);
// замещает операцию класса Observer
virtual void Draw();
// замещает операцию класса Widget;
// определяет способ изображения часов private:
ClockTimer* _subject;
) /
DigitalClock::DigitalClock (ClockTimer* s) {
Паттерны поведения
subject = s; subject->Attach(this);
DigitalClock::~DigitalClock () {
_subject->Detach(this); }
Прежде чем начнется рисование часов посредством операции Update, будет
проверено, что уведомление получено именно от объекта таймера:
void DigitalClock::Update (Subject* theChangedSubject) { if (theChangedSubject == _subject) { Draw ();
void DigitalClock::Draw () {
// получить новые значения от субъекта
int hour = _subject->GetHour(); int minute = _subject->GetMinute();
// и т.д.
// нарисовать цифровые часы
Аналогично можно определить класс Ana logC lock:
class AnalogClock: public Widget, public Observer { public:
AnalogClock(ClockTimer*);
virtual void Update(Subject*);
virtual void Draw();
'/
Следующий код создает объекты классов AnalogClock и DigitalClock, которые всегда показывают одно и то же время:
ClockTimer* timer = new- ClockTimer;
AnalogClock* analogclock = new AnalogClock (t imer);
DigitalClock* digitalClock = new DigitalClock(timer);
При каждом срабатывании таймера timer оба экземпляра часов обновляются и перерисовывают себя.
Известные применения
Первый и, возможно, самый известный пример паттерна наблюдатель появился в схеме модель/вид/контроллер (МУС) языка Smalltalk, которая представляет собой каркас для построения пользовательских интерфейсов в среде
Паттерн Observer
Smalltalk [KP88]. Класс Model в MVC - это субъект, a View - базовый-класс для наблюдателей. В языках Smalltalk, ET++ [ WGM88] и библиотеке классов THINK [Sym93b] предлагается общий механизм зависимостей, в котором интерфейсы субъекта и наблюдателя помещены в класс, являющийся общим родителем всех остальных системных классов.
Среди других библиотек для построения интерфейсов пользователя, в которых используется паттерн наблюдатель, стоит упомянуть Interviews [LVC89], Andrew Toolkit [P+88] и Unidraw [VL90]. В Interviews явно определены классы Observer и Observable (для субъектов). В библиотеке Andrew они называются видом (view) и объектом данных (data object) соответственно. Unidraw делит объекты графического редактора на части View (для наблюдателей) и Subject.
Родственные паттерны
Посредник: класс ChangeManager действует как посредник между субъектами и наблюдателями, инкапсулируя сложную семантику обновления.
Одиночка: класс ChangeManager может воспользоваться паттерном одиночка, чтобы гарантировать уникальность и глобальную доступность менеджера изменений.
Дата добавления: 2015-09-11; просмотров: 89 | Поможем написать вашу работу | Нарушение авторских прав |