И результат мне очень понравился, сам паттерн реализован по классической схеме GoF на интерфейсах, а не как в JAVA, где для субъекта (источника сообщений) необходимо наследоваться от абстрактного класса java.util. Observable, что в виду отсутствия множественного наследования уменьшает полезность данной реализации.
Что добавилось в rtl:
В модуле Classes определены интерфейсы для субъекта и наблюдателей, а также тип уведомления (изменение, удаление субъекта?, добавление/удаление элемента и пользовательское) :
- Код: Выделить всё
Type
// Notification operations :
// Observer has changed, is freed, item added to/deleted from list, custom event.
TFPObservedOperation = (ooChange,ooFree,ooAddItem,ooDeleteItem,ooCustom);
{$INTERFACES CORBA}
{ IFPObserved }
IFPObserved = Interface [BaseGUIDObserved]
// attach a new observer
Procedure FPOAttachObserver(AObserver : TObject);
// Detach an observer
Procedure FPODetachObserver(AObserver : TObject);
// Notify all observers of a change.
Procedure FPONotifyObservers(ASender : TObject; AOperation : TFPObservedOperation; Data : Pointer);
end;
{ IFPObserver }
IFPObserver = Interface [BaseGUIDObserver]
// Called by observed when observers are notified.
Procedure FPOObservedChanged(ASender : TObject; Operation : TFPObservedOperation; Data : Pointer);
end;
Новый тип исключений:
EObserver = Class(Exception);
очевидно, что оно «бросается» при попытке добавления в список наблюдателей объекта не реализующий интерфейс IFPObserver.
Замечу, дополнительно, что перед описанием интерфейсов «наблюдателя» присутствует директива
- Код: Выделить всё
{$INTERFACES CORBA}
что означает, что они не наследуются от IUnknown – и при использовании данных интерфейсов не будет никаких «сайд» эффектов автоматически создаваемых\удаляемых экземпляров, как это подразумевается при использовании технологии COM.
Ну и самое главное – классы TList и TPersistent теперь реализуют интерфейс IFPObserved, т.е. они и их потомки теперь могут регистрировать наблюдателей! И посылать уведомления о своем состоянии (изменении состояния). Теперь дело за разработчиками LCL – ведь все компоненты наследуются от TPersistent (кроме того от него же наследуются и TStrings) – и это означает, что в скором времени можно будет наблюдателем подключаться и получать уведомления от любого компонента, например TButton и т.д..
Т.к. в TPersistent – методы реализующие интерфейс IFPObserved – объявлены в секции Protected, то только разработчики наследников решают будет ли доступна данная функциональность пользователям их классов.
В FCL_Base
Появился модуль fpobserver. В нем объявлено несколько классов, смысл использования для меня остается не до конца очевидным. Это классы TObservedHook и рад классов посредников (Mediator) наблюдателей.
Насколько я понял TObservedHook это для делегированной реализации в своих классах субъектах:
- Код: Выделить всё
TMySubject = class(IFPObserved)
Private
fObservedHook: TObservedHook;
…
Public
…
Property Observed: TObservedHook read fObservedHook implements IFPObserved;
….
End;
на этом по наблюдателям в 2.6.2 все. Если кто знает как обычно используются посредники в паттерне "наблюдатель" киньте ссылку пожалуйста.