No, let’s continue our discussion about principles, Cairngorm principles. As a general advice for studying somebody’s else code, you should always start with looking at the events. But first, let’s discuss the package names (which will be the same for your application skeleton) : business – contains service classes , commands - contains the application commands , control - contains the events , event dispatcher and the application controller , model - contains the application’s data, view - will get filled with GUI components , vo – will be filled with value objects for the business engine.
Let’s open the CairngormEvent.as to take a look inside : as I’ve said in the previous post, a CairngormEvent has the ability to dispatch itself – the public method dispatch calls for the CairngormEventDispatcher (which is Singleton) and do it – between us, doing so assures that the event in not a volatile object, eaten away by the Garbage Collection (I’ve seen some nasty bugs related to this). There is something even more interesting (for those of you who never thought that you can do so) in the CairngormEvent class – the public property data, which allows you to pass the reference to an object with the event – the data passed can be used by other listeners, but there is a catch : the listeners will have to know that object’s type.
So, we can make some corrections to this class, in order to make it more OOP principles compliant : first, we could add to the constructor another parameter (by default null) to declare the carried object. Secondly, we could use a setter getter for the data property – thus respecting the encapsulation. We can also define a cast property, making the data getter return data as cast (the lazy way to avoid writing every time this inside some other class).
Paying a visit to the CairngormEventDispatcher.as will bring to our attention the following : first, it is a Singleton which makes use of an instance of EventDispatcher (through it’s interface IEventDispatcher) which will do all the dispatcher work. You can notice that this class could declare it’s implementation to IEventDispatcher, since all the required methods are declared.
FrontController is the class which you will need to extend to create your application controller – it will basically associate an event to a command – when that event occurs (usually as a result as a user interaction with a GUI component) the associated command will get triggered – which will affect either the model, either will create a delegate which will make a service call and return the result to that command (which will modify the model, of course).
Using a Dictionary of commands, the FrontController doesn’t need to iterate through an array when it needs to execute that command. Adding a command (registering it) creates a dictionary entry with the name of the event associated with the reference to the command class which is associated to it – looking first for the uniqueness of that event name. I’m advising you to take a good look of this technique – you might find it very useful and applicable somewhere else, for example a large collection of value objects which has the constrain to identify unique objects very fast.
The above classes represents the main event engine behind Cairngorm – simple, yet very efficient.
The Command class will get extended for each and every command your application needs – as previously explained. As you saw inside the FrontController, every event will create a new instance of the associated command and a call to the execute method will be made. The SequenceCommand class will be extended when you need to execute a chain of commands as a consequence of a single event – which is pretty useful when your application needs to load or alter relational data.
There is not much to say at this moment about ModelLocator and its interface IModelLocator , because you will organize your application’s model after its needs – the most important principle is that the GUI elements will bind to the declared properties (and don’t be afraid to use complex properties like extensions of ArrayCollections – but never ever dispatch events as seen in many applications). The ValueObject class is deprecated since version 2.1 of Cairngorm – so don’t bother to look at it. If you need to improve your code readability you can use the interface IValueObject – meaning that you can point out a generic value object where needed (assuming that that value object will evolve and you don’t need each and every single property of it).
Getting to the view related classes, ViewLocator will be used to register GUI components since ViewHelper is deprecated. As you can see, the same technique is used for registering GUIs to this Singleton class as in FrontController’s case. Commands which will interfere with the GUIs does not need to know the name of it, but it will use the ViewLocator which will return the instance of that class – so it will can manipulate it. You will see in some other MVC frameworks like pureMVC that a mediator is used to control a GUI element, but Cairngorm has no notion of it.
After you’ll get some experience in getting yourself organized after the Cairngorm principles, I’m convinced that you will find your way of adding more patterns to it – in order to become your pattern. For now, it is important that you, as a “young padawan” to concentrate over respecting basic principles, to make use of data binding and change watchers (knowing exactly what you do – recommended reading is about propertyChange events dispatched). Don’t listen to people which says “data binding is bad” and be careful what you learn – think how easy it is to learn something the wrong way, but how hard it is to forget it afterward.With patience and a strong will for experimenting (let’s say you will decide to refactor one of your projects to Cairngorm) you will get to the point where you’ll have a lot of alternatives and solutions by your side.
I will continue “the Way I See It” series with the last part of Cairngorm, trying to point out some of the improvements that other developers created for it.