There is no "good" or "best" way to implement patterns.
The implementation you choose depends on how you want to use it.
You could for instance also use the generics feature (available since Delphi 2009) to simplify the use of a lot of patterns.
And if you use Pre Delphi-3 versions, or want to avoid reference counting
you cannot use interfaces.
(Reference counting can open a new can of worms when mixed with traditional Owner/Ownee based life time management; be sure to descend classes that expose interfaces from the right ancestor - like TInterfacedObject - and watch your life time management).
Apart from the "pure" question on how to implement the observer pattern, it is also good to be able to recognize classes in Delphi that implement the observer pattern.
For instance the TDataSet/TDataSource also implement the observer pattern.
The whole concept of Data Aware Controls depends on it, all bound through the TDataLink.
I have written a TDataLinkReflector component based on the TDataLink
, which reflects all the virtual methods in TDataLink
to events in TDataLinkReflector
.
Base on TDataLinkReflector
I wrote TDataAwareControlController components that does all kind of interesting things to Data Aware Controls based on the TDataSet, its TFields and the TDataSource linking to the TDataSet (coloring on read-only, required, etc).
But even a seemingly simple thing like events can be seen as based on that pattern (though events are single cast, so only one observer can watch one event).
Another class implementing this is the TApplicationEvents; each instance lets you listen to any of the events on TApplication.
I hope that sheds some light on where the observer patterns is used in Delphi.
--jeroen
PS: Anyone interested in the components I wrote might want to see the CodeRage video mentioned here.