Swiz vs RobotLegs
Recently I spent some time converting a medium-sized project first to Swiz and then to RobotLegs. The following is my take on the two frameworks and how I chose a winner. Right now there are definitely a lot of things I like about both frameworks, and I wish I could pick and choose the features I like best. I would call it the Peanut Butter Framework Mashup Extraordinaire.
I have considered giving Mate and Parsley a similar go but Swiz and RobotLegs were the two that definitely interested me the most so I’ve done them first. I’m pretty familiar with Cairngorm and don’t personally like it. I think I’ve read and tinkered with PureMVC enough to know that it isn’t my ball of wax either.
Keep in mind that I am refactoring an EXISTING project to use these frameworks. I am not starting a project from scratch. If I were then I might feel differently. Maybe.
What is important to me?
The most important things about a development tool, be it an IDE, a library, a repository or a framework is:
- How quickly can it help me get the job done?
- How quickly can it help me add new features?
- How quickly can it help me find and squash bugs?
- How little code can I write to get the job done?
And that’s it really. I want to write as LITTLE easily understandable code as possible and I want to be able to easily fix it and add to it.
Don’t code it ’till you need it.
For me writing code is not always a task of reuseability. If I build something for a project then it’s for THAT project. If I see that some piece of code could be helpful elsewhere then I will take the time to make that piece a project and allot it its own time. By carefully choosing what gets “bumped up” into reuseability land I am able to get the job done faster and with less effort.
With that in mind it’s important that the framework I’m using allow me to do that; write code quickly. That isn’t to say I’ll settle for spaghetti code just because it closes the job ticket faster. I know I’ll also be the one adding features to this puppy and fixing bugs. So I want it to stand the test of time. So the framework will also need to gently guide me to do that as well.
Map Commands vs Mediate Methods
One difference between Swiz and RobotLegs seems to be how they handle “triggered logic”.
Using Swiz you define instances of Controllers in your Bean Map. In those controllers you will have a number of methods that get called when an event is fired that Swiz captures (mediates).
You can use events to trigger calls to methods in RobotLegs as well but only in certain siturations (Mediator classes). It seems to instead suggest that you map Commands to Events, a technique which I was first introduced to in Cairngorm. The WAY this happens is different than Cairngorm, but the idea is roughly the same: When X happens this Command Class is created and executed.
That’s actually how the project was working before the conversion (though it was using a home-rolled solution for that).
Now I LOVE commands. I really like to use my own command library. I don’t always want to have to link a command up to an event. With my library I can play with my commands from anywhere in my code. Generally I don’t care when a command starts, finishes, etc except from where I actually called the command. This helps me keep my code-base as small as possible; needless custom events aren’t created when only one place cares about something happening. When I DO find that event information is helpful elsewhere then I can just dispatch some informative events from the command itself (using whatever the framework of the day is). With this in mind any tool that lets me to easily continue working in this manner is a win for me.
Using RobotLegs I’m able to map an Event to a Command. Awesome. I can even inject some data into it. Cool. But the Command needs to be an ICommand. And I couldn’t find ICommand in the library so AFAIK the commands actually have to extend robotlegs.Command. Not cool. I have dozens of commands already written and tied to another library. I could just change the Commands that need to be triggered by events but that sounds like a royal pain-in-the-ass and additional work == bad thing.
Using Swiz I’m not able to map the commands to events. I don’t like that. However I CAN create and execute the commands from the Controller. The Controller is mapped from the same BeanMask that the model objects are mapped in and it just contains a bunch of methods that get called when events fire (defined by MetaData). That actually gives me a little more control. I can inject the dependencies into my existing commands if I want to. But in my project all of my commands actually have constructor parameters. So I just inject properties into my Controller and using that and the properties on the dispatched events I handle the execution of the commands. It’s not incredibly elegant but it gets the job done and there isn’t much code to write or change.
Getting Events Out There
Bubbled events are cool right? Sure they are technically “expensive” and there are the rare cases of apps fighting each other over bubbled events that they throw at each other. A “Bubble Fight” I call it. Personally I’ve never witnessed one.
RobotLegs is very strict about NOT relying on the DisplayObject tree as a means to move event messaging back and forth (bubbling). Swiz lets you do just that. Bubble an event up from any attached view and any methods assigned to that event will be called. Easy-peasy. That’s another win for Swiz.
Singletons are Awesome
No their not.
Fortunately both frameworks allow you to more elegantly handle Singletons and actually ALL the data that exists in a project. Using DI (Dependency Injection) you can have objects that the framework is aware of injected right into your classes. Both use some type of MetaData to define that. [Autowire] is Swiz’s and [Inject] is RobotLegs, but it comes down to the same thing.
DI allows you to do away with the classic “Singleton” pattern. Class.getInstance() sucks. Even when you don’t care about reuseability it still sucks. As far as the injecting/tagging goes I can’t say that I’ve got a preference. But for registering these items I like Swiz better.
In RobotLegs you have a class that kind of “kick starts” things. One popular place to put the items to be injected is there. I understand, however, that you can actually do this in a number of places in a number of ways. That sounds like trouble to me.
In Swiz the accepted way of doing this is in an (M)XML document; the BeanMask. This document will define all of your “model” objects. These are the objects that can be [Autowire]d. That seems clean to me and I like it. You can have multiple Bean Masks if your project gets large, but at least you’ll know where to look for stuff.
Code from Behind vs Reach Around
I’ve got a number of views that are small. Small enough that I just put the necessary view logic in a <Script/> tag.
Sometimes that logic will grow and grow and I’ll just pull it out into it’s own class. Usually I just do a code-behind. (The MXML class extends an ActionScript class which has all the logic in it.)
Previously I had a “Global Event Dispatcher” that my views listened to. Methods were called when those events were dispatched from that “Global Event Dispatcher”.
RobotLegs doesn’t like that. I need to have a Mediator class for my logic. Then I need to bind that mediator class to the view. But not actually IN the view. Or even in the mediator (though the mediator should have a REFERENCE to the view). The binding takes places somewhere else. If I don’t play by those rules then I don’t get the benefit of mediated methods for my view.
Swiz doesn’t care. I can just stick [Mediate] on any public view method (<Script/> or code-behind) and it will work just fine. I’m not opposed to mediator classes. I think that is a fine (and cleaner) alternative to a code behind. But I don’t want to HAVE to do it that way. Unfortunately, that method DOES need to be public, which I DON’T like. I think I can get over that, but it’s essentially an event handler. It’s not something that anyone outside of that view needs to know about.
Services
Ok, I honestly didn’t put either framework through the paces when it came to working with my Services. All of my service handling is already done in a way that is already clean and I saw no need to change that at all. This wasn’t an important part of either framework for me.
Best Practice vs Get ‘er Done
Shaun Smith had a great piece about “why RobotLegs”. And I couldn’t help but get fired up about his reasons. They are good ones. But they seem like good reasons on paper, not necessarily in practice. Like I said, if I had started this project out fresh instead of trying to port it then I might feel differently. But when I look at all the code I would have to change/add using RobotLegs that shows me that there might be a lot of code that I shouldn’t have to write.
When I ported everything to Swiz it took me a couple of hours and I had things rolling. I was able to change just a portion of my application to rely on the framework. It worked alongside what I already had. But it took me the better part of some valueable sleepy-time to get RobotLegs working. And even then I still had mountains of Mediators to create before the app was truly “working”. Don’t think I’m a hater. I DO really like what RobotLegs is all about. But it’s just not for me; it doesn’t fit my workflow or my coding style.
Swiz does.
It’s late
If I’ve gotten anything wrong describing the usage of either of those frameworks then please correct me. I admit that I am a total n00b at both of these. I tried to keep it general and relatively vague; there are plenty of other resources that explain how these things actually work much better than I could.
Sleepy time.
Jason,
This was an interesting read, particularly as I am currently looking at Swiz. All the Swiz examples/tutorials I have seen on the ‘net are very small apps so I would be interested to know what “a medium-sized project” is in your eyes. The reason I ask is simply that my last real experience of Flex was 3 years ago when I used Flex 1.5 with Cairngorm 0.99. I found that using Cairngorm whilst building small projects seemed like overkill and the only benefit I really was was that I could look at a Cairngorm project structure and dive in straight away knowing where each piece of code was. In fact I haven’t used Flex commercially since v1.5 but I am keen to get back to it and finding a lightweight framework is important to me. (Oh and for clarification I am not bashing Cairngorm. I used versions 0.95/0.99 only).
Nick
Hey Jason,
sorry to hear that using Robotlegs was so much work for you.
I guess having to use the mediators isn’t great when porting existing code that relies on self-mediated views that directly talk to the framework. On the other hand you could pretty easily create a sort of catch-all mediator and map it to all views with MediatorMap#mapView(‘qualifiedClassNameOfConcreteView’, CatchAllMediator, ViewBaseClass) to give the views direct access to the frameworks’ event bus. If you have a base class that all your views extend, that is.
As for the commands: Robotlegs doesn’t force you to extend any class, ever. The classes in the “mvcs” package are just one implementation of the core framework in “core”, consisting of interfaces only.
You’ve just got us at an unfortunate time with that. As of last week, Robotlegs doesn’t rely on an ICommand interface to ensure command compatibility anymore. Instead, you can plug in any class you want, provided it’s got an execute method. Therefore, the ICommand interface was removed. The unfortunate thing about the timing is that parts of the documentation don’t yet reflect that change.
In general, you don’t _have to_ bind commands to events to dispatch them, you can also create and execute them manually. You have to use injector.instantiate if you want to get DI for them, though.
Much of the rest is a matter of taste, I guess. For example, to me, bubbling events, while sometimes handy, add lots of potential for very hard to debug problems.
cheers,
till
Great writeup, Jason. Since you seemed to be open to new view communication patterns, I figured I would mention my preference for the Presentation Model pattern. In my opinion it fits Flex/MXML(C) better than code behind. In case you haven’t already seen it, I created an example Swiz application that uses the pattern here: http://www.benclinkinbeard.com/2009/05/swiz-example-application-with-presentation-model-pattern/.
What! This is an outrage!
I kid, but let’s review the evidence (I like to believe that I could have been a sleazy Private Investigator if I wasn’t so in love with computers):
http://pbking.com/blog/?p=197 – By Friday you’d played with Swiz and watched the awesome Swiz In 20 Minutes screencast. We don’t have a cool video like that (#RobotlegsFail) primarily because we’ve been pushing really hard to get v1.0 out the door.
http://pbking.com/blog/?p=201 – On Tuesday you noticed (whilst still playing with Swiz) that properties need to be public to be injected into (a little flaw in AS3, and not specific to any DI driven framework). If you’re anything like me, this would indicate that you’d been playing with Swiz over the weekend. Anyhoo, Tuesday (night?) is when you decided to give Robotlegs a shot.
http://pbking.com/blog/?p=203 – And here we are, one day later. To drive the point home, you spent much more time with Swiz than Robotlegs.
Now, I agree that Swiz is very easy to pick up after watching the Swiz In 20 Minutes screencast. The current Mvcs implementation of Robotlegs, on the other hand, is quite similar to PureMVC (without the cruft) – I’d argue that anyone with any serious PureMVC experience under their belt would be able to pick up Robotlegs as quickly as, if not more quickly than, Swiz. But therein lies a double-edged sword: if you don’t enjoy the Mediator pattern, the extra classes are going to feel like boilerplate.
Also, the Mvcs implementation is but one implementation of Robotlegs. Once v1.0 is properly released (we’re on v1.0RC5 at the moment.. it’s getting a little silly) I’ll whip up some alternative (read: Less PureMVC-like) implementations – at least one of which will enable the Presentation pattern.
Anyhoo, I’m commenting here just for the lolz. Swiz is a great framework, with a truly awesome team behind it. Once they’ve modularized it and made it pure AS3 compatible I’m going to have great fun getting stuck in and trying to find new bits to gripe about ;)
Cheers,
Shaun
This is awesome. I love that so many people are so fired up about their frameworks! Keep in mind that I think both of these are AWESOME pieces of code. My initial experience with RobotLegs was VERY positive. I really liked where it was going. http://twitter.com/jcristpbking/status/5402529634
I do want you to know that I didn’t work with Swiz over the weekend. I do my best to stay away from my keyboard as much as I can from Friday evening to Monday morning. The actual time logged on each framework (and I am very anal about that) was notably more in RL than Swiz. You do mention that somebody more intimately familiar with PureMVC could have probably picked it up faster. While I’m familiar with the concepts of PureMVC I haven’t actually given it enough time to be “familiar”. The Swiz quickstart was awesome to be sure. But the RL documentation I found did seem like enough to get me to where I needed to me. But perhaps not.
Mediators are definitely a good pattern and one I have in my toolbox. My issue is just that I don’t want to be required to do anything any particular way. I don’t always see view mediators (or presentation) as the best solution to the problem at hand. I understand that’s a trade-off; standardization vs flexability but one I’m willing to make to gain what I see as efficiency.
Till, I wasn’t able to find a way to use my existing classes and gain property injection and all of the other cool toys without extending the RL command. If I knew how to do that then that would be a big help for sure. Nor could I find a way to handle the bubbles. A “master mediator” seems like a step in the wrong direction to me. Writing more code is not what I’m looking to do.
RobotLegs is great. The concepts are sound. But I’m just looking for a tool that augments the way I do things and allows me the flexibility to work the way I think is best. I’ll definitely be keeping my eye on the 1.0 release and all the additional documentation and examples that will come along with that.
Heh, so perhaps I’d make a worse PI than I thought. With regards to the Command thing, you can now map any Class that implements an execute method – including your existing Command classes. Extending the provided Command class is just a handy way to set up some dependencies; if you choose not to extend it, and you still want access to the cool toys, for example, the context’s Event Dispatcher, just declare it as dependency in your class definition.
Good to know that. But will the commands still be property injectable? Or at least can I specify params to pass to the Commands constructor?
Certainly. A command’s dependencies get fully resolved before execute is called. DI is handled by SwiftSuspenders which supports: field, setter, method and constructor injection. http://github.com/tschneidereit/SwiftSuspenders/blob/master/README.textile
Robotlegs is really just a way to share an Event Dispatcher and a Dependency Injector between objects in a given scope. The Mvcs implementation adds some additional tools to enable a PureMVC-like workflow. Another implementation might offer tools to enable a more Swiz-like approach; it would be trivial to take the modular design of Robotlegs and make it more convenient to use by providing static helpers, but much more of a challenge to take a static framework (or application) and make it modular.
Of course, statics simply don’t worry some people, and that’s totally cool. I always chuckle a little when I think of that UI testing framework that clashes with apps under test if they happen to have been built with the same framework.
Shaun,
The idea of making RobotLegs work “my way” is really intriguing me. You give a good point about modular > staticy vs static > modular.
I think I spent too much time trying to make my project bend to the “documented” or “default” way of using RobotLegs. Perhaps instead I should be focusing on getting RobotLegs to work the way I want it. Hopefully I can even do that without changing any of the RL code.
The view part is still getting me though. I don’t want to HAVE to use view mediators. And tyeing them to views elsewhere just doesn’t make sense to me (from a get ‘er done perspective). I want a way to be able to use a single MXML file with view logic, code-behind, presenter, etc if I want to. And I don’t want to have to tell the framework how that works.
Event bubbling I see as a way of decoupling that event driving from any framework; that’s one reason I like bubbling events. I certainly welcome other solutions but it’s gotta stay simple.
This is what is going to make Robotlegs really exciting over the coming months. There are so many options for implementations and incorporating design patterns. Right now it is a breath of fresh air for those of us coming from PureMVC. I know the MVCS implementation is Shaun’s albatross. It is awesome, to have a default implementation to show what the framework can do, but at the same time folks tend to assume the framework IS the implementation. I made the same assumption in my first blag on the subject.
Mediators don’t need to have any knowledge what-so-ever about the guts of your view components. Code behind, presenter, bubbled events, whatever you like. The mediator sits there waiting to hear and event it is explicitly listening for. You can mediate granularly, or mediate a container and listen for bubbled events from its sub-components. Whatever sort of messaging you want to distribute to glue your applications actors together, you can listen for. No more, no less.
Refactoring a code base that has already seen a lot of decision making in regards to architecture presents particular challenges. This is especially true with the default implementation as it is fairly prescriptive. I’d love to hear your opinions while approaching a fresh app.
This article is great! Thank you for taking the time to do the testing and document your findings. I’ve been looking at both frameworks and this is very insightful.
So I finally got round to making a little screencast to illustrate the flexibility of the Legs:
http://shaun.boyblack.co.za/blog/2009/11/10/robotliz-using-robotlegs-like-swiz-in-20-minutes/
It doesn’t make for a very well written app, but it might give you some ideas for alternative implementations.
Hi Jason,
Nice comparison article. I’ve worked with Swiz before and it is so far, my favorite micro architecture for flex. Minimal boilerplate, and no required hard dependencies on any piece of the MVC (except I guess, the initial SwizConfig).
I, too, hated the fact that I had to publically expose some of those methods in my Controller. However, I have learned to live with it. In my project, I initially did not find a reason to inject controllers, so it wasn’t an issue really – there were no references to deal with. When I found a reason to, I created an interface for the controller which did not expose the public methods/properties. In that way, it felt less “dirty”. The same is true for public properties used for DI.
While I limit the access of properties/methods in my beans through the interface, the public properties/methods that aren’t in the interface helped me a lot while unit testing. I can inspect those properties and directly call those methods to see what would happen. In fact, during the test set up, I usually do some manual injections to my controllers/models to give it some mock objects to work with.
Again, the convenience of having them public in a limited-usage scope personally helped me out.
As I migrate my application to using more of a “Presenter” pattern for the views the publicly exposed methods bother me a lot less since it’s part of an included class instead of a parent (in code behind) or just self. Though for quickies I still shamelessly write logic in tags of my views.