Another Architectural Framework, But Why?

robotlegssketchsmall

The State Of The Game

There are some great Flash and Flex application frameworks out there right now. Mate, Swiz and PureMVC (update: and Parsley!) stand out. The authors of these frameworks realized that the Flash Platform is different enough to the JVM to warrant a fresh approach to application design.

Someone mentioned recently that for such a young language (referring to Action Script 3), it’s quite surprising how many frameworks have sprung up around it. I’m not surprised at all: rich internet application development is complicated.. and it’s a pretty recent field in the grand scheme of things. It brings new (and often subtle) twists to traditional web and desktop software development. Writing elegant, maintainable code is hard enough as it is, but doing so on a rapidly evolving, heavily interactive platform.. well, people are still working on the best way to approach that (unless I missed the big news – in which case you can stop reading right here).

Hence all the groovy new architectural frameworks popping up. They share some common goals:

  1. Help developers write good, clean, understandable, testable, maintainable code
  2. Help them write that code faster
  3. Provide an easy-to-use mechanism for application/context/module subsystem inter-communication
  4. Provide an easy-to-use mechanism for wiring distinct parts of the application together whilst keeping those parts loosely coupled

And they succeed. To various degrees. I think they’re all pretty cool.

scenery

A Poke In The Back With A Sharp Stick

So why build another one?

  1. For fun – it’s how I learn stuff
  2. Because I find the other frameworks critically flawed

What kind of “critical” flaws?

  1. Singletons (big “S”)
  2. Central/Static Event Dispatchers
  3. Using the Display List as an Application Event Bus
  4. Casting
  5. The Service/Model Locator Pattern
  6. The Presenter Pattern
  7. Injecting into View Components

And what’s wrong with those things?

They are bad ideas:

1. The Singleton – Bad Idea

The standard Singleton implementation (that static getInstance method) is severely flawed. Unless you are writing device drivers, there is almost no excuse to touch a Singleton with a sharp stick.

Singletons bring bags of hurt to frameworks and applications.. suddenly, trying to build a modular application becomes an overly complicated affair, and unit testing becomes a nightmare. Singletons are viruses – they infect every class they touch.

And Multitons? If Singletons are evil, Multitons are diabolically evil. What makes the Multiton pattern incredible is that it manages to chump the Singleton as the worst Design Pattern Of All Time – no easy feat, and certainly the work of an evil genius with a wicked sense of humour. Not only do we have all the problems of the classic Singleton, we throw a poorly designed Model Locator into the mix – to pull out these horrendous Singletons we now need to use String keys.

Contextual singletons (as made possible by Dependency Injection frameworks) are a much nicer solution, they don’t require any extra (fluffy, nonsense, ill placed) code on the target classes themselves, and they allow identical applications/modules to exist side-by-side in the Virtual Machine without fighting and mass confusion. Which leads me to..

2. Central/Static Event Dispatchers – Bad Idea

As convenient as it is to use, a Central Dispatcher is a really bad idea. Another Singleton effectively. Pop two apps into the same SWF and watch, with excitement and glee, all the cross-talk that occurs – both apps responding to each other’s events. Oh noes!

Architectural frameworks generally provide you with an application event bus/channel/dispatcher to “chat” on, but this should be localised to the application itself (or some other context). Which leads me to…

3. Using the Display List as an Application Event Bus – Bad Idea

I find this one fairly disturbing too: dispatching system/application events along the display list. No!

A View is just that: “A view”, not “The view”. And don’t get me started on those innocent looking Event Maps! No, let’s move along…

4. Casting – Bad Idea

Besides wasting space and annoying programmers, casting distributes knowledge throughout a system – casting requires that you look elsewhere in your codebase for the “real” type.

And it weakens our lovely compile-time type checking (albeit temporarily), sending us back in time to our unhappy days building complex applications in the Flash IDE. And it’s boring. And it often occurs because of..

5. The Service/Model Locator Pattern – Bad Idea

Classes should not be responsible for “fetching” their dependencies – this is a separate responsibility that belongs somewhere else entirely – they should only contain code for doing their job. When classes reach outside to fetch things from the application/context they sneakily hide their dependencies away from the outside world.

Unit testers will despise you (which is a serious problem if you are writing your own tests) because it becomes incredibly hard to figure out how much set up needs to be done to write even the smallest of tests. You have to look inside the class for any calls to the Service Locator to find your direct dependencies, and then you have to look inside each of those classes to find theirs and so on. No no, that’s just cruel.

6. The Presenter Pattern – Bad Idea

Ok, it’s going to be tricky to back this one up. But think about it this way: the Presenter pattern requires that you modify your View component (to add a reference to a Presenter). Not a biggie, but once you’ve done that you’ve started coupling your View component to your application/context – a slippery slope.

I think the Mediator pattern is a much better fit for Flash and it’s Display List, and even more-so when it comes to Flex (and other UI frameworks with complex component life cycles).

It is far easier and cleaner to “wrap” around view components and poke their APIs than to have to modify (extend) them to make space for their Presenter references. Leave those components alone, leave them to the component developers, you’re supposed to be writing an application. While we’re on the Presenter pattern, let’s take a look at something dirty one might do in an attempt to salvage it’s reputation..

7. Injecting into View Components – Bad Idea

Besides being incredibly slow and wasteful (especially for Flex UIComponents), injecting directly into a View component couples it to your application/context.

View components, with any hope for reuse, should be as self-contained as possible. They should expose an API and dispatch Events. They shouldn’t be dependent on the application they are in or the framework it happens to be using. Give ’em ViewModels (M-V-VM) if you must, but don’t go and couple those ViewModels to your application, and certainly don’t inject them.

ducksaysyuk1

Wrapping Up This Micro-Post

Well that’s just your opinion, dude

Yeh, but I’m pretty proud of my little 7 point list there (cos I’m an OOP noob, and this stuff gets me amped). Using Dependency Injection I was able to avoid all those nasty things when building my own PureMVC-like framework.

But that just shifts the problem somewhere else

Yes, somewhere more appropriate.

Besides some convenient implementations (in the mvcs package), and some marker interfaces (in the core package) RobotLegs essentially provides two things:

  1. A Command Factory – for binding Commands to Events, and
  2. A Mediator Factory – for handling automatic Mediator creation and registration

Everything else is handled by a Dependency Injection framework and an Event Dispatcher.

theendissmall

Note: If you’ve been through all this before, I apologise, it’s new to me.. I’m a little slow.

Beware: the current default implementation of RobotLegs makes use of annotated setter injection. This breaks encapsulation, is open to misuse, and runs the risk of leaving objects in partially initialised states, but it’s very convenient! You can swap out SmartyPants-IOC for a Dependency Injection framework that performs constructor injection if you really want to play it safe.

I’ll admit straight-up (albeit as a footnote) that I never really gave Cairngorm much of a chance – preliminary research led me to demos, documentation and diagrams that screamed poor design and foreshadowed immense struggle. I’m sure there is a way to build a well designed Cairngorm application, but it looks like it’d take an awful amount of effort.. and code. And it probably wouldn’t be very much fun.

UPDATE: Removed some words that made me sound like a douche bag.

Posted in Banter, Code, Robotlegs | Tagged , , , , , , , , | 39 Comments
  • Darren

    Great post, Shaun. I’m looking forward to trying RobotLegs but I think I’ll wait until it supports constructor injection.

    I’m currently using Cairngorm and I find it very intuitive but obviously it’s guilty of 1,2,3 and 5 on your list in particular. However, I find it very fast to develop in and usually uses less code than PureMVC for example. I also find it very easy to maintain – the structure is very prescribed so it’s obvious where to look to find a bug. Only my top-level components reference the model directly and I use a sort of custom DI to inject into anything lower. If I’m going to make the leap to a radically different framework, I want to go all the way and do it right as Misko Hevery’s blog has been making a lot of sense to me lately.

    I wonder how your framework handles view notifications, in particular how to notify multiple views simultaneously of the result of a db interaction, for example. If there’s a failure or another type of warning/message as a result of the interaction, ie. the data in the model hasn’t changed, do you set a flag and/or have a message queue on your model which passes the info to all child components through binding? Can you sequence commands?

    Finally, I often find that a lot of the sort of reasoning you use above to be based on theoretical, rather than real-life limitations, or to make unit-testing easier (admittedly can be an important consideration). After all, Cairngorm with all it’s theoretical flaws has been used successfully on many of the largest Flex apps around. Your “Beware” section at the end suggests to me that you’re aware of this trade-off too – to paraphrase: “I know it’s fragile but it’s so convenient and I trust myself to do it right”. Surely, you could apply this logic to careful use of Singletons too. Sometimes I wonder at all the extra effort I go to to make my components reusable when I very, very rarely reuse them in other projects.

  • Darren

    Great post, Shaun. I’m looking forward to trying RobotLegs but I think I’ll wait until it supports constructor injection.

    I’m currently using Cairngorm and I find it very intuitive but obviously it’s guilty of 1,2,3 and 5 on your list in particular. However, I find it very fast to develop in and usually uses less code than PureMVC for example. I also find it very easy to maintain – the structure is very prescribed so it’s obvious where to look to find a bug. Only my top-level components reference the model directly and I use a sort of custom DI to inject into anything lower. If I’m going to make the leap to a radically different framework, I want to go all the way and do it right as Misko Hevery’s blog has been making a lot of sense to me lately.

    I wonder how your framework handles view notifications, in particular how to notify multiple views simultaneously of the result of a db interaction, for example. If there’s a failure or another type of warning/message as a result of the interaction, ie. the data in the model hasn’t changed, do you set a flag and/or have a message queue on your model which passes the info to all child components through binding? Can you sequence commands?

    Finally, I often find that a lot of the sort of reasoning you use above to be based on theoretical, rather than real-life limitations, or to make unit-testing easier (admittedly can be an important consideration). After all, Cairngorm with all it’s theoretical flaws has been used successfully on many of the largest Flex apps around. Your “Beware” section at the end suggests to me that you’re aware of this trade-off too – to paraphrase: “I know it’s fragile but it’s so convenient and I trust myself to do it right”. Surely, you could apply this logic to careful use of Singletons too. Sometimes I wonder at all the extra effort I go to to make my components reusable when I very, very rarely reuse them in other projects.

  • Hi Darren, thanks for the feedback.

    I know what you’re saying about theoretical vs real-life problems. Which is why I don’t think you have to wait for constructor injection before you give RobotLegs a whirl! Here are my thoughts on constructor vs setter injection (esp with regards to Mediators):

    http://shaun.boyblack.co.za/blog/2009/05/01/constructor-injection-vs-setter-injection/

    I’ll respond to your other questions momentarily!

    Cheers,

  • Hi Darren, thanks for the feedback.

    I know what you’re saying about theoretical vs real-life problems. Which is why I don’t think you have to wait for constructor injection before you give RobotLegs a whirl! Here are my thoughts on constructor vs setter injection (esp with regards to Mediators):

    http://shaun.boyblack.co.za/blog/2009/05/01/constructor-injection-vs-setter-injection/

    I’ll respond to your other questions momentarily!

    Cheers,

  • Pingback: Constructor Injection vs Setter Injection « shaun smith()

  • Darren, regarding Cairngorm: it really is on my list of things to learn, I’m just waiting for that up-to-date, golden “Cairngorm Tutorial” – I found it too time consuming trying to distinguish between good and bad Cairngorm resources the last time I looked into it.

  • Darren, regarding Cairngorm: it really is on my list of things to learn, I’m just waiting for that up-to-date, golden “Cairngorm Tutorial” – I found it too time consuming trying to distinguish between good and bad Cairngorm resources the last time I looked into it.

  • Darren, regarding your last point: I fully agree, as developers we have to evaluate the pro’s and con’s of the case at hand to balance purity against reality. However, the patterns I mentioned above are one’s that I think are critically flawed – they are flawed in both theory and reality. But I’m still new to all this, so I may be overlooking many finer details..

    I’ll get to the view notification stuff in a sec.. after some fine nourishment!

  • Darren, regarding your last point: I fully agree, as developers we have to evaluate the pro’s and con’s of the case at hand to balance purity against reality. However, the patterns I mentioned above are one’s that I think are critically flawed – they are flawed in both theory and reality. But I’m still new to all this, so I may be overlooking many finer details..

    I’ll get to the view notification stuff in a sec.. after some fine nourishment!

  • Pingback: RobotLegs AS3: System/Context Event Flow « shaun smith()

  • maciek

    hey.. we were all responsible buddy.

  • maciek

    hey.. we were all responsible buddy.

  • PeZ

    What’s so wrong with using the Display List as an ‘application bus’?

  • PeZ

    What’s so wrong with using the Display List as an ‘application bus’?

  • maciek: haha buddy!

    PeZ: because it binds your ‘application’ to your ‘view’. If you need to drastically restructure your view there is a very good chance you’ll break your application. Also, the display list (with event bubbling) is a linear, ‘upwards’ kind of event bus: you can dispatch events to your parents, but not your siblings – perfect for view related events, but not very good for application-wide communication.

  • maciek: haha buddy!

    PeZ: because it binds your ‘application’ to your ‘view’. If you need to drastically restructure your view there is a very good chance you’ll break your application. Also, the display list (with event bubbling) is a linear, ‘upwards’ kind of event bus: you can dispatch events to your parents, but not your siblings – perfect for view related events, but not very good for application-wide communication.

  • Very interesting post. I’m a Cairngorm user purely based on it’s the framework I’m most comfortable with. Do I know it’s flawed. Ofcourse. But so is everything else in Actionscript. I guess the bottom line is as long as you are happy. A happy programmer is happy client. Mmmkay. (Ok maybe not always)

    Anyways keep up the good work. Like the blog.

  • Very interesting post. I’m a Cairngorm user purely based on it’s the framework I’m most comfortable with. Do I know it’s flawed. Ofcourse. But so is everything else in Actionscript. I guess the bottom line is as long as you are happy. A happy programmer is happy client. Mmmkay. (Ok maybe not always)

    Anyways keep up the good work. Like the blog.

  • Greg Baker

    Ok, I like the ideas you have presented.
    I have one issue though: that is, I am looking for an AS3 implementation independent of the Flex Framework; …without the bloat of Flex. Something MXML based for use with the Flex Builder, but mainly avoiding the UIContainer and such classes. I am building such an example ‘though I am not a “framework developer.” So, is the core DI/IoC implementation of your RobotLegs usable w/o the core Flex Framework?

    Greg

  • Greg Baker

    Ok, I like the ideas you have presented.
    I have one issue though: that is, I am looking for an AS3 implementation independent of the Flex Framework; …without the bloat of Flex. Something MXML based for use with the Flex Builder, but mainly avoiding the UIContainer and such classes. I am building such an example ‘though I am not a “framework developer.” So, is the core DI/IoC implementation of your RobotLegs usable w/o the core Flex Framework?

    Greg

  • Hi Greg,

    RobotLegs AS3 can be used for both Flex and plain ActionScript projects in Flex Builder (soon to be Flash Builder), or any IDE/compiler that can work with SWC library files.

    Currently, it depends on SmartyPants IOC – which in turn has a couple of core Flex Framework dependencies. But these few dependencies are bundled into the SmartyPants SWC file – hence the ability to use RobotLegs in pure ActionScript projects.

    I did some size tests a short while ago (so things may have changed a little, but not much):

    RobotLegs + SmartyPants:
    D: 27,959 bytes
    R: 19,299 bytes

    SmartyPants:
    D: 23,073 bytes
    R: 15,970 bytes

    Thus, RobotLegs (without SmartyPants):
    D: 4,886 bytes
    R: 3,329 bytes

    PureMVC Multicore:
    D: 6,847 bytes
    R: 4,215 bytes

    D = Debug Build Size
    R = Release Build Size

    Bear in mind that if you are already using Flex, the weight added by SmartyPants might be less that the figure above. If you are building a pure ActionScript project however, the total weight added will be about 19kb.

    Also, just to clarify, RobotLegs itself is just an MVCS micro-architecture. By default, it makes use of SmartyPants for Reflection and DI/IoC, but this can be changed by providing custom adapters. If I can find (or build) smaller/faster/better libraries for Reflection and DI, I will provide adapters for those, and switch the defaults to point to them.

    I’d like to see a configuration with 0 Flex dependencies, where RobotLegs + Reflection + DI < 12kb.

    If you decide to take RobotLegs for a spin, don't hesitate to send any questions to the discussion group – I will do my best to answer promptly! http://groups.google.com/group/robotlegs

  • Hi Greg,

    RobotLegs AS3 can be used for both Flex and plain ActionScript projects in Flex Builder (soon to be Flash Builder), or any IDE/compiler that can work with SWC library files.

    Currently, it depends on SmartyPants IOC – which in turn has a couple of core Flex Framework dependencies. But these few dependencies are bundled into the SmartyPants SWC file – hence the ability to use RobotLegs in pure ActionScript projects.

    I did some size tests a short while ago (so things may have changed a little, but not much):

    RobotLegs + SmartyPants:
    D: 27,959 bytes
    R: 19,299 bytes

    SmartyPants:
    D: 23,073 bytes
    R: 15,970 bytes

    Thus, RobotLegs (without SmartyPants):
    D: 4,886 bytes
    R: 3,329 bytes

    PureMVC Multicore:
    D: 6,847 bytes
    R: 4,215 bytes

    D = Debug Build Size
    R = Release Build Size

    Bear in mind that if you are already using Flex, the weight added by SmartyPants might be less that the figure above. If you are building a pure ActionScript project however, the total weight added will be about 19kb.

    Also, just to clarify, RobotLegs itself is just an MVCS micro-architecture. By default, it makes use of SmartyPants for Reflection and DI/IoC, but this can be changed by providing custom adapters. If I can find (or build) smaller/faster/better libraries for Reflection and DI, I will provide adapters for those, and switch the defaults to point to them.

    I’d like to see a configuration with 0 Flex dependencies, where RobotLegs + Reflection + DI < 12kb. If you decide to take RobotLegs for a spin, don't hesitate to send any questions to the discussion group - I will do my best to answer promptly! http://groups.google.com/group/robotlegs

  • Greg Baker

    Thank you for a quick and detailed response.
    I will take your RobotLegs for a spin in the near future; work often gets in the way exploration and Monday is but a sleep away.

    Greg

  • Greg Baker

    Thank you for a quick and detailed response.
    I will take your RobotLegs for a spin in the near future; work often gets in the way exploration and Monday is but a sleep away.

    Greg

  • Yeh, I hear ya! No problemo. Cheers,

  • Yeh, I hear ya! No problemo. Cheers,

  • I am sold sir. Sucks that it is 1am, because I am ready to get into it.

  • I am sold sir. Sucks that it is 1am, because I am ready to get into it.

  • Pingback: RobotLegs AS3: A Dependency Injection Driven MVCS Framework for Flash/Flex – Inspired by PureMVC | Joel Hooks()

  • Pingback: shaun smith » RobotLegs Updates, Demos and Unit Testing()

  • Pingback: shaun smith » WTF Is RobotLegs?()

  • Haski

    Nice post.

    How do you test your view then if you don’t use Presentation model?

  • Haski

    Nice post.

    How do you test your view then if you don’t use Presentation model?

  • With difficulty 😉

    No, I assume that most of the view components that I mediate have been thoroughly tested elsewhere. The idea with the Mediator pattern is that your view components are stand-alone and portable. If we’re talking integration testing, then I *could* test my Mediators with mock view components. Most of the time, however, I’m more interested in testing my application (models, services, commands) than my view.

  • With difficulty 😉

    No, I assume that most of the view components that I mediate have been thoroughly tested elsewhere. The idea with the Mediator pattern is that your view components are stand-alone and portable. If we’re talking integration testing, then I *could* test my Mediators with mock view components. Most of the time, however, I’m more interested in testing my application (models, services, commands) than my view.

  • Pingback: Swiz vs RobotLegs : Peanut Butter Thoughts()

  • Hi Shaun

    Im not a flex developer but have been building flash applications now for some time and like you spent much time learning about as much as possible , and then also creating my own workarounds. I reached the realms of reading up about design patterns in the beginning of last year and am still growing my own personal practices with all the knowledge obtained. I see you feel very strong about the points mentioned above but also you seem open to discussions or a choice disagreement, So Im going to disagree with you on point 1 and point 2 and also reference the last point of concern by Darrens response to your post. Firstly there are many arguments pro and con about singletons all over the web , these debates extend to further debates within each pro or each con with even finer smaller dogmatic ideas or personal rationalisations towards each matter of concern, I personally found myself jumping to one state of belief for a time and then totally going another direction after that .. but all this had to happen while I am employed at a new media agency where there main point of concern is turn around times. What this situation has brought about after 5 years of push and pull is finding a perfect balance for both worlds. I achieved this by constantly re-factoring / rewriting my code library and ideas over and over and over again. I now have an AS2 / AS3 framework that has exactly the same syntax for use from the API point of view , how big is the framework?? its not big .. point! It comprises of the very basic building tools needed to put together (quickly) any RIA. It uses a central event dispatcher(point 2) which i named a communicator and does not suffer from your quote ” both apps responding to each other’s events. Oh noes!” scenario ever. It also uses a singlton for this (point 1) and functions perfectly in any actionscript environment I dont want to let this response get to long winded , so to sum it up , Just as all flash objects extend from Object , I have one class named AbstractController , which creates/registers its scope to the central communicator, and all my framework objects be they bussiness logic or view controllers extends this class except for VO's or DTO's. As Darren mentioned about all the extra effort to make uber reuable / scalable frame works is not always practical , and quote wikipedia on IoC http://en.wikipedia.org/wiki/Inversion_of_control : “There are in the end five classes needed to switch a lamp after pressing a button” or “macaroni code[citation needed] (in the extreme: methods with only one line of code that merely act as gateway to the next layer).” as you can see .. I eventually decided Im not sold on this matter of extreme design pattern coding mayhem because in conclusion , 90% of the time , the real world implementation of whatever im going to build never needs it. what I found I (and my employer and our clients) need the most is… TIME! So I keep to my simple yet very extendable small RAD framework concept now and build classes that buy me time with mundane tasks like buttons , xml pagination , animation effects etc..

  • re: using the display list as a event bus (Mate, I'm looking at you…); the biggest problem I've identified is that if you have a component dispatching a commanding event (event mapped to a command), and the component is removed from the display list prior to the commanding event dispatch, you get a silent failure (ergo, nothing). This has happened several times on a current project I'm on that is using Mate in it's default config, where a module dispatches an uninitialize event but the parent has already unloaded and removed the component instance prior to the cleanup/uninit event raising. This means, there is a dependency created on the proper functioning of the component to it's membership in the display list at the time of sending an event, which anyone outside the component, even n levels up the display list, can change at any time.

  • “Well , the view of the passage is totally correct ,your louis vuitton handbags details is really reasonable and you guy give us valuable informative post, I totally agree the standpoint of upstairs. I often surfing on this forum when I m free and I find there are so much good information we can learn in this forum!