×
Namespaces

Variants
Actions

Обозреватель (Observer)

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata

Статья
Перевод:
Оригинал: Observer
Carbider
Последнее редактирование: hamishwillee (09 Dec 2011)
----

Шаблон проектирования Observer (обозреватель) используется для реализации следующей логики: наблюдаемый объект, при изменении собственного состояния, производит оповещение объектов-обозревателей, которые должны предварительно зарегистрироваться (подписаться на изменения). Наблюдаемому объекту ничего не нужно знать об обозревателях, кроме набора вызываемых callback-функций, описанных в интерфейсе (M-классе). Такой шаблон достаточно часто используется при разработке ПО для Symbian C++.

Пример интерфейса обозревателя

class MMyObserver
{
public:
enum TMyEvent
{
EMyEvent1,
EMyEvent2
};
virtual void HandleMyEventL(TMyEvent aEvent) = 0;
};


Для получения событий, класс должен реализовать интерфейс обозревателя:

// заголовочный файл
class CMyObserver : public CBase,
public MMyObserver
{
//...
private:
virtual void HandleMyEventL(TMyEvent aEvent);
//...
};
// cpp файл
void CMyObserver::HandleMyEventL(MMyObserver::TMyEvent aEvent)
{
switch (aEvent)
{
case MMyObserver::EMyEvent1 :
{
//...
}
break;
case MMyObserver::EMyEvent2 :
{
//...
}
break;
default :
break;
}
}

Для того, чтобы подписаться на изменения, объект-наблюдатель должен передать указатель на самого себя (this) наблюдаемому объекту:

void CMyObserver::ConstructL()
{
//...
iObjectSendingEventsToItsObservers->SetObserver(this);
//...
}

Для этого, наблюдаемый объект должен содержать необходимые функции для регистрации наблюдателя:

// заголовочный файл
class CObjectSendingEventsToItsObservers : public CBase
{
public:
//...
void SetObserver(MMyObserver* aObserver);
//...
private:
MMyObserver* iObserver;
};
// cpp файл
void CObjectSendingEventsToItsObservers::SetObserver(MMyObserver* aObserver)
{
iObserver = aObserver;
}

При изменении собственного состояния, наблюдаемый объект может оповещать зарегистрированного обозревателя, вызывая соответствующие функции:

if (iObserver)
{
iObserver->HandleMyEventL(MMyObserver::EMyEventX);
}

Для оповещения множества наблюдателей, можно использовать массив, в котором хранить указатели на все оповещаемые объекты:

// заголовочный файл
class CObjectSendingEventsToItsObservers : public CBase
{
public:
//...
void SetObserverL(MMyObserver* aObserver);
void RemoveObserver(MMyObserver* aObserver);
//...
 
private:
//...
void NotifyObserversL(MMyObserver::TMyEvent aEvent);
 
private:
RPointerArray<MMyObserver> iObserverArray;
};
// cpp файл
void CObjectSendingEventsToItsObservers::SetObserverL(MMyObserver* aObserver)
{
iObserverArray.AppendL(aObserver);
}
 
void CObjectSendingEventsToItsObservers::RemoveObserver(MMyObserver* aObserver)
{
TInt pos = iObserverArray.Find(aObserver);
if (pos >= 0)
{
iObserverArray.Remove(pos);
}
}
 
void CObjectSendingEventsToItsObservers::NotifyObserversL(MMyObserver::TMyEvent aEvent)
{
for (TInt index = 0; index < iObserverArray.Count(); index++)
{
iObserverArray[index]->HandleMyEventL(aEvent);
}
}
 
CObjectSendingEventsToItsObservers::~CObjectSendingEventsToItsObservers()
{
iObserverArray.Close();
}
This page was last modified on 9 December 2011, at 05:01.
65 page views in the last 30 days.
×