h1

When in Rome…

August 12, 2008

use dependency injection.

Recently, when working on a Flex project, and being the numpty that I am, I was trying to work out how to design the app for the usual stuff (extensibility, maintainability, etc). It’s a GUI app with several components, and it needs to interact with various web services, so I went for an engine / GUI split as a starting point. All the code that directly deals with user actions, UI controls, and UI layout lives in a “ui” package, and all of the code that modifies application state, controls reading / writing data, and does the “business logic” (such a hateful term – is there a better one?) lives in an “engine” package. Application actions are executed following the Command pattern, and there are some data objects that live in a “data” package that talk to the web services and store data on disk, providing methods for reading and writing data that the engine code can use.

All seems well and good so far (unless I’ve already made some horrible mistake – <fear/>), but I now need a way of linking the engine components (called things like UserPreferencesManager) and the UI components (called things like UserPreferencesDialog) together. Typically, there will be one UserPreferencesManager (or whatever) for the application, and the preferences will need to be accessed all over the shop. Several options spring to mind:

  • Instantiate a UserPreferencesManager object as a member of the Application object, then access it from everywhere else using the handy ActionScript object “Application.application
  • Make the UserPreferencesManager a singleton (there’s only going to be one of them, right?)
  • Make the UserPreferencesManager a global static object
  • Instantiate a UserPreferencesManager object as a member of the Application object, then expose a property on all components requiring access to a UserPreferencesManager, and follow the Dependency Injection pattern to set each property to our application’s UserPreferencesManager (directly in the Application definition for children of Application, then from those objects to their children that require access to the UserPreferencesManager, and so on)
  • Use the Model Locator pattern

To be honest, these options didn’t spring to mind the first time I wrote a Flex app. I found out about Application.application and thought “great, that makes all this design pattern rubbish totally irrelevant – I can bind straight to the object wherever I am! Woohoo!”. Naturally, when I wanted to change one of these objects in my Application that was coupled to everything else, things started to look less rosy, so I asked my old friend Google for help.

Google sent me to the Adobe Developer Centre page linked to above, which made me very happy indeed. Some advice on the very problem I was struggling with, straight from the horse’s mouth! I read about their Model Locator pattern and it all made sense. I already knew what a Singleton was, and while I’d avoided that because I had some vague notion that it might behave very much like the Application.application method, Model Locator was a rubber-stamped, ready-made solution. Right?

Fortunately I found the Architectural Atrocities blog series, which has quite a lot to say about Flex, and Cairngorm in particular (which is what the Model Locator pattern comes from – I’ve never used the framework myself). The relevant part:

Translation:

We though all the patterns in the J2EE catalog looked too complicated so we came up with this idea of using global variables instead, it’s much easier.

Indeed the Model Locator is just another, more complicated way of writing a singleton (or global variable, if you like your bad programming to be more obvious). Strangely, the Adobe authors do mention the correct solution in their article:

This brings up an important best practice. When you create components that rely upon client-side data, it is all too easy to create a direct reference to a Singleton model, such as ShopModelLocator. Indeed this is true throughout the application. We discourage this approach. Instead, consider passing the model and/or its properties down through a hierarchy of your view components, for a cleaner and more thoughtful solution.

That’s dependency injection! Why bother with the singleton at all? If you just want one ShoppingCart object, just create one instance. There’s no reason to make the shopping cart object a Singleton – that just makes your life more difficult if you decide in the future that actually, you do want more than one shopping cart.

So I’ve been using dependency injection, and it’s great. It makes it obvious which classes depend on which objects, even if they’re nested several levels deep (because their parents, and their parents’ parents, etc, all need to have the dependencies injected into them). If you change your object instance, you’ll get compile errors (if you’re using type annotations in Flex, or otherwise statically typing your variables in other languages). You can even have more than one object of a given type if you like!

To summarise the methods listed above, then:

  • Global variable
  • Global variable
  • Global variable
  • Single instance that is passed around where it is needed
  • Global variable

It’s impressive how many different names there are for the same thing (and that’s not even mentioning Monostate). Yes, I know there are subtle differences and they’re designed to do slightly different things… but really.

My Command invoker is still a singleton though.

Advertisements

3 comments

  1. Even though I think you’re on the right track to a good solution for your UserPreferenceManager I would like to point out a problem. You risk putting yourself in the position described by the anti-pattern called “propagating dependency”. Simply put you are likely to find yourself having classes that are passed the UserPreferenceManager only to satisfy the dependency of another class (e.g. the MainView needs the UserPreferencesManager only to propagate it to, say, PreferencesView). In a way one could argue that just passing an object down the object hierarchy isn’t dependency injection at all since it passes the object to classes that don’t strictly have a dependency on it.

    The way to get rid of that problem is either to wire up the object structure in one place so that dependencies are only passed to the objects that actually depend on them. This is how most dependency injection frameworks work, they read some kind of description of all dependencies and have a container that does the instantiation and wiring. In Flash/Flex that Prana is an example of this solution.

    The other way is to use the application framework Mate, which has a feature called Injectors that listen for initialization events from the views and inject the dependencies at that point (and sets up a binding while it’s at it, making it even more powerful).

    If you’re interested in a really good Flex application framework and think that dependency injection is a good solution I really think you should look at Mate (http://mate.asfusion.com). It is, in my opinion the only contender on the Flex application framework scene. As you seem to have noticed all the others think that global variables is a good solution to most problems.


  2. Hi Theo,

    First of all, thanks for leaving the first ever comment on my blog, and making it more intelligent than “omg I got the first post!!1!one!”. I’ve been doing this blog for a whole two days now, and I’m already learning things from it – good stuff.

    I am indeed in danger of propagating dependencies – in fact I believe I may have made a small amount of progress down that road already. It’s nice to know that there are frameworks that help remove this problem. I’m still relatively new to Flex, so it will be interesting to give things like Mate a try.

    One of the more concerning aspects of Flex is that the Adobe “guidance” and “best practices” are so hit-and-miss, which is fairly off-putting for people learning the technology. Even some of the core Flex libraries and ActionScript language features are terribly designed. It might be a result of its Flash ancestry, but the UI parts seem to be much higher quality than the data structures / algorithms behind it all. It really needs something like the C++ standard template library to provide some good data structures to build apps with. Or maybe I just haven’t got my head round it yet…


  3. I agree completely. In general the Flex framework is the best I’ve worked with, I’ve never been so productive. But when it comes to the details it’s as you say, you shake your head and wonder what on earth they were thinking.

    Consider the Flex collections API, it’s so monstrously bad in its design that it isn’t even funny. The two main interfaces are ICollectionView and IList, but none of them are usable by itself, you have to have a combination of both, the ArrayCollection class. It’s like it was designed to be the exact opposite of “program to interfaces, not implementations”. The next episode of Architectural Atrocities is probably going to about the collections API.



Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: