Actual code samples makes things make so much sense. And this is a great example of the (new to me) Robotlegs framework. I really like what I see. The following post has the same small app in several different frameworks.
Robotlegs example project with source
Any comparison of frameworks wouldn’t be complete without Robotlegs. I included Robotlegs in my session at LFPUG recently, but didn’t post the example project here because the framework was in a state of flux. Robotlegs is now settling down as it approaches its imminent 1.0 release, and the MVCS implementation in it is unlikely to change further, so here’s my example.
For this Robotlegs example I’ve used exactly the same project as in the previous examples for other frameworks. Robotlegs is not prescriptive about your application’s architecture, but it does include a default MVCS implementation for those that wish to use it. I’ve used that default implementation here.
Working with this kind of code outside of some sort of IDE or at least a well known convention could be a little baffling. For example, for this project, small though it is, sets the feeds with interfaces and not the actual feeds. This goes along with the principle of “Program to an interface, not an implementation” which is good and flexible. But to a newbie it might a bit confusing. (See here for a discussion about extending AS3 using interfaces, or rather the difficulties in doing so.)
FlexBuilder is a great IDE for AS3, granted there aren’t many. And for those with far more experience in more mature languages like Java with its plethora of incredible tools, it really pales in comparison. But it’s a far cry better than the Flash AS editors! I bring that up because I often learn code by the awesome Command+click (Ctrl+click on a PC?) to jump to the definition of a variable or a class. Opening up Flexcaster.mxml shows a context “FlexcasterContext” and a MainView. I was completely new to IoC programming with its dependency injection. So I didn’t know at that time that a context is a term commonly used in IoC. But I knew it’s an MVC framework so I figured the code I was looking for wasn’t in the view. 🙂
Clicking on the FlexcasterContext brought it up which showed where the magic happens: how everything is connected. Of note though are these two lines:
injector.mapClass( IFeedsService, OpmlFeedsService );
injector.mapClass( IFeedService, RssFeedService );
This lets me know that wherever I see IFeedsService it’s actually using OpmlFeedsService, and the same for RssFeedService and IFeedService. Through the rest of the code you won’t see any reference to OpmtFeedsService or RssFeedService. This context is the only place I would see where the connection is made. The author actually brings this issue up in a different version that also uses IoC but instead of events, it uses Signals.
All in all I think it worked out rather well. There may even be a potential future in an architecture like this. I do fear the explosion of interfaces and injection rules may make the approach unwieldy for a large project, but perhaps multiple DI configuration classes, a clear package structure and disciplined developers is all that’s required. I welcome your opinions on this.
There is more discussion there. Of course the immediate benefit of programming to an interface is that swapping out a class is a one line change instead of refactoring all affected code. Making mock data objects for the model while testing is a great example of that. It could instead be
injector.mapClass( IFeedsService, TestOpmlFeedsService );<br />
when doing tests which simply returns a preset array of data.
Overall I have to say I like the conciseness of the code. Even little things like having classes instantiated as a Singleton is cool.
injector.mapSingleton( FlexcasterModel );
The FlexcasterModel is just a class but the framework itself handles the instantiation via injection. Saying
mapSingleton
makes sure you only have one and when it is injected, only the one instance already created is passed in. As the robotlegs site says, this helps prevent the boilerplate code. I look forward to trying out the framework. I enjoyed using PureMVC once I wrapped my head around it but this, perhaps because of the conciseness, took far less time to grasp.