Thursday, 30 June 2011

Modified Command Pattern

Recently I came across a problem of how to implement common interface for executing commands on objects of different types. Only one command can be assigned to each object. Each command has different implementation for each type of object but commands are accessed on each object through same interface. I wanted to have something like this:

I came up with the solution which uses abstract class (CCommand) in order to achieve common interface (Execute()) and command classes templated on actual object type in order to specialize Execute() implementation for each type.

Command.h:



CommandAdd.h:


CommandRemove.h:


UpdateGroupsCollection.h:


CUpdateFilesCollection.h:


main.cpp:


Output:

Group1 added to Update Groups
File1 added to Update Files
Group1 removed from Update Groups
File1 removed from Update Files

To avoid having SetCommand()/GetCommand() code repeated in all client classes, we can use intermediate class, let's call it CCommandManager. This simplifies client classes - they just need to contain one instance of CCommandManager and perform all command-related actions through it:

CommandManager.h:


UpdateGroupsCollection.h:


CUpdateFilesCollection.h:


main.cpp:


Templated commands can be avoided if commands become inner classes of all classes they need to be performed on. E.g.

UpdateGroupsCollection.h:


main.cpp:

Friday, 24 June 2011

Two implementations of Observer pattern

Change in some object (publisher, notifier, subject) very often needs to be reflected in another one (subscriber, observer). Publisher can have multiple subscribers, and can notify them on different changes (events, notifications). Subscribers implement handlers for each event they are interested in.

Publisher can have references to all subscribers and through them call event handlers but this makes these objects tightly coupled. Publisher's code would need to be changed in order to add a new subscriber and remove existing one; if some subscriber wants to use different event handler or to change the name of the existing one, publisher's code must be altered. We want to avoid this. Actual publisher must not know about actual subscriber.

Observer pattern decouples publisher and subscriber by introducing an abstract layer through which they talk. Frequently cited solution (which is the one presented in "Design Patterns: Elements of Reusable Object-Oriented Software") still does not achieve full object decoupling: actual subscriber maintains a reference to actual publisher. Furthermore, it does not cover model when publisher passes notification to subscriber.

Following solution overcomes these problems. It defines CEvent class which represents notification (with its unique ID and data). Publisher creates event and passes is to subscribers. Publisher (not any of subscribers) is responsible for CEvent memory cleanup.



Output:

CActualObserver::OnEventIntValChanged(): new int value: 123
CActualObserver::OnEventTextChanged(): new Text value: test1
CActualObserver::OnEventTextChanged(): new Text value: test1
CActualObserver::OnEventTextChanged(): new Text value: test2
CActualObserver::OnEventTextChanged(): new Text value: test2


In this implementation a single class - CNotifier - serves any type of event but the price we needed to pay for this is the lack of type safety: void* casts should be avoided!

If we don't want to use CEvent (with that awful void* member), but still want to have generic solution, we can make CObserver and CNotifier templated on event type:



Output:

CActualObserver::OnEventIntValChanged(): new int value: 123
CActualObserver::OnEventTextChanged(): new Text value: test1
CActualObserver::OnEventTextChanged(): new Text value: test1
CActualObserver::OnEventTextChanged(): new Text value: test2
CActualObserver::OnEventTextChanged(): new Text value: test2