Improving Cairngorm’s ModelLocator Part 6 - Conclusion
22nd May 2008
In the previous articles I’ve outlined some alternatives to the standard practice of using a Singleton as the ModelLocator in Cairngorm. I’ve tried all three of the alternatives I outlined in a real project so here’s a summary of my opinions about them and the standard singleton.
Singleton
Pros:
- Well known design pattern (other developers understand it with little explanation).
- Singleton is enforced by blocking the constructor (there are various ways to do this).
Cons:
- Difficult to mock for testing.
- Changing code to allow more than one instance is not trivial.
- Class can’t easily be extended.
Singleton factory
Pros:
- Separates singleton behaviour from the model class
- Model class can be extended in the normal way.
- Multiple instances can be created and used with no alterations to the code.
Cons:
- There is no protection to enforce the singleton – we rely on developers to remember to use the SingletonFactory.
Hiding the singleton
Pros:
- Behaviour added by simply extending a predefined class.
- Model class can be extended in the normal way.
- Multiple instances share the same data so instance creation is standard, using
new.
Cons:
- The data is copied between instances, so multiple instances means multiple copies of the data which means increased memory use.
- Because multiple instances all share the same data, there is no option for multiple sets of data.
The monostate
Pros:
- Behaviour added by simply extending a predefined class.
- Model class can be extended in the normal way.
- Multiple instances share the same data so instance creation is standard, using
new. - Can have instance data as well as shared data.
- Data can be switched from shared to instance specific simply by changing the getter/setter for the property.
Cons:
- Model class definitions are more complex (requiring the use of getter/setter pairs for every piece of data).
Conclusion
I’m sure there’s more pros and cons to be outlined – please add them in the comments below.
My own conclusion is that the monostate is the best solution, but it is hampered by the non-trivial implementation for the model classes due to the need for getter/setter pairs for each property (although some would say this is a good thing). It’s worth noting, however, that the resulting code is no more complex than the code generated by the compiler from the bindings in the other techniques – it’s just that we have to write this code ourselves. An automated tool to convert properties to appropriate getter/setter pairs when compiling would make this technique far and away my favourite (ant task, anyone).
If you don’t want to have to write getters and setters for each piece of data in the model then any of the other techniques are worth considering. My own favourite would be the Singleton Factory. As long as your developers remember to use it, everything works very neatly.
An apology
Finally, an apology for the rambling nature of this set of posts. When I started I only intended to write one post, then as I worked with the problem another post emerged, etc. Had I planned it in advance the posts would have be structured better.
See also:
- Improving Cairngorm’s ModelLocator, Part 1 - The problem.
- Improving Cairngorm’s ModelLocator, Part 2 - Hiding the singleton.
- Improving Cairngorm’s ModelLocator, Part 3 - Hiding the singleton II.
- Improving Cairngorm’s ModelLocator, Part 4 - The monostate.
- Improving Cairngorm’s ModelLocator, Part 5 - The singleton factory.
Read more articles about Flex, Actionscript 3

12 Comments add your own
Hi Richard,
Great article. Here is a Flex Builder/Eclipse plug in to help you generate getters/setters.
http://www.dreaminginflash.com/2007/12/21/auto-generate-getters-and-setters-in-flex-builder/
Eric | 22nd May 2008 at 8:23 am
Thanks, this has been a good series of posts with some good arguments.
I have one small critisism of your arument in favour of singleton factory:
“Multiple instances can be created and used with no alterations to the code.”
Multiple instances are not a singleton, so you are breaking the pattern. Also this promotes the misuse of Singletons, Im sure you’ll agree that they are overused and misunderstood by many developers - they should only be used when you must have one and only one instance of the class. To quote the ease of creating multilple instances is in danger of propogating the misuse/misunderstanding of singletons in the first place.
Apologies if I have not understood the agenda of your singleton factory - hopefully you’ll be able to answer this for me.
Thanks
Matt
mattjpoole | 22nd May 2008 at 10:16 am
As far as I have seen all your alternatives are just variations of hiding the global variable (a.k.a the singleton) so that it doesn’t look like a global variable. It doesn’t actually solve the problem, it just makes it less obvious.
The solution in Part 2 is essentially Monostate, at least in practice. So is the solution in Part 3. In Part
Part 4 you describe an actual Monostate, which is nothing more than global variables behind a facade. In Part 5, finally, you describe a static factory, which, when used this way, is just another kind of global variable.
The problem isn’t that Cairngorm has singletons, the problem is that it uses them as global variables. Your solutions are just variations on this problem. I suggest looking at solutions that don’t involve global variables at all, like Dependency Injection.
Theo | 22nd May 2008 at 11:47 am
Eric - thanks. I wasn’t aware of eclipse monkey. Will take a look.
Matt - The idea of the SingletonFactory is to separate the factory that manages the singleton from the class itself. The class becomes a normal class from which we can create as many instances as we like. The SingletonFactory is a way of creating and managing global access to a single instance of this class. This makes it possible to also create other, local, instances of the class if required or to reuse the class in another project where multiple instances are required.
richard | 23rd May 2008 at 9:48 am
Theo said - As far as I have seen all your alternatives are just variations of hiding the global variable (a.k.a the singleton) so that it doesn’t look like a global variable. It doesn’t actually solve the problem, it just makes it less obvious.
Removing globals is not the goal. Making code easier to develop and maintain is.
The solution in Part 2 is essentially Monostate, at least in practice. So is the solution in Part 3.
The solution in part 3 is just an improvement on part 2 so they can be considered as one. The interesting part of this solution is what happens behind the scenes, where the code is a hybrid of singleton and dependency injection through binding. Each instance has its own data, separate from the other instances. The required data is injected into the instance by the singleton, via the bindings. But from the outside it looks like a monostate.
In Part 4 you describe an actual Monostate, which is nothing more than global variables behind a facade.
A monostate is a class whose instances share some common state between them. The only thing that is global is the class constructor, but all public classes have class constructors that are globally accessible. This is not a bad thing.
In Part 5, finally, you describe a static factory, which, when used this way, is just another kind of global variable.
Being a function, we can alter what it returns by altering the function body. This enables us to modify the object returned without altering the classes that use the object. This is a distinct improvement on a global variable. It can be improved further – passing an interface to the function rather than a class, and having a concrete instance that implements the interface returned, would be one improvement. I grabbed the function from a previous post without thinking too hard if it could be improved for the purpose here. I apologise for that.
The problem isn’t that Cairngorm has singletons, the problem is that it uses them as global variables.
Global access is one of the two properties of the Singleton pattern. If it doesn’t have global access, then it isn’t a Singleton. And if one doesn’t intend to use the global access one shouldn’t use the Singleton pattern.
I suggest looking at solutions that don’t involve global variables at all, like Dependency Injection.
A simple DI implementation would involve passing the model data around from class to class, probably passing it into the constructor of each class that needs it. This works and I would advocate it on a small project. But this naïve implementation of DI can get unwieldy with larger projects. At that point one might turn to a DI framework of some form.
But why use both a DI framework and Cairngorm? If one uses DI, it would seem a good idea to replace both the Service Locator and the Model Locator with DI oriented implementations, and then there’s not much of Cairngorm left. I can see a very strong argument for creating an alternative to Cairngorm that uses DI throughout but it was not my intent here to advocate scrapping Cairngorm, I’m just looking to improve it. Forcing Cairngorm to use DI feels like forcing a square peg into a round hole. I don’t have much experience with DI frameworks so would value your opinion on this.
richard | 23rd May 2008 at 11:48 am
Removing globals is not the goal. Making code easier to develop and maintain is.
You do realise that this is a contradiction?
Theo | 26th May 2008 at 3:12 pm
I don’t have much experience with DI frameworks so would value your opinion on this.
It’s not a DI framework as such, but have a look at Mate, it’s a Flex application framework that doesn’t go down the global variables-route like the rest of them.
Instead it does what the others say they do: make it easier to write reusable, decoupled code. It’s new and untested, but given the state of Flex application frameworks I think it’s more or less the only contender.
I don’t think that DI needs a framework to be workable, for me it’s more of an approach to architecture, the don’t-call-us-we’ll-call-you (a.k.a the Hollywood principle) makes it easier to design for low coupling and high reusability.
Now, to some counter-counter-comments:
The only thing that is global [in Monostate] is the class constructor, but all public classes have class constructors that are globally accessible.
As you very well know the key feature of Monostate is that the state is kept in static variables. Static variables are by definition globals. It doesn’t matter that you create instances of a monostate, because the instances are only access points to the global variables.
MyMonostate.myVarand(new MyMonostate()).myVarare equivalent statements and both access a global variable. This is what I mean by Monostate being a facade to global variables, in the second example it doesn’t look like you access a global variable, but that is in effect what you do.Being a function, we can alter what it returns by altering the function body. This enables us to modify the object returned without altering the classes that use the object. (about part 5, the singleton factory)
Except that that is the opposite of what you describe in part 5. You describe a registry which keeps instances of classes that you pass to it. You explicitly tell the registry that you want the instance of a specific type. By design there is no possibility to alter what the factory function returns.
The point of factory method pattern is to decouple you from the instantiation and concrete implementation of that which the factory creates, usually by specifying that it returns an interface type. In your version you specify the class (i.e. the concrete implementation) explicitly, which removes that benefit.
Your singleton factory is a place to store global variables. It moves the responsibility of enforcing the singleton-ness, but it is still just a variation of global variables.
To sum up my criticism of your suggestions: global variables are never a good idea because they make an application tightly coupled, leads to less reusable, less testable and less modularisable code. All your suggestions are just variations of global variables and have the same bad consequences. In my opinion no better than what Cairngorm offers by default, although that is pretty bad to start with.
However, I think you’ve made a good effort of trying to avoid the major shortcoming of Cairngorm, but I also think that you need to look more deeply at what, exactly, the problem really is. It is not that Cairngorm uses the Singleton pattern, the problem is that it is designed to use global variables. To solve the problem the global variables must go and with them, most likely, the singletons, but hiding the singletons will not solve anything.
Theo | 26th May 2008 at 3:53 pm
–Removing globals is not the goal. Making code easier to develop and maintain is.
You do realise that this is a contradiction?
No. If making code easier to develop and maintain is the goal, then removing globals can only be the goal if the two are synonymous. I don’t agree with such absolutism. There may be other ways to make the code easier to develop and maintain, and removing globals doesn’t always make the code easier to develop and maintain (although often it does). So, no I don’t see why my statement is a contradiction.
richard | 26th May 2008 at 5:02 pm
Mate looks very interesting. After a brief look I like what I see and I will take a longer look at it soon. Thank you for bringing it to my attention..
For the counter-counter-counter comments…
As you very well know the key feature of Monostate is that the state is kept in static variables. Static variables are by definition globals.
The monostate uses private static variables. The scoping of these variables is the class itself. They are not accessible from outside this scope and hence are not global.
MyMonostate.myVar and (new MyMonostate()).myVar are equivalent statements and both access a global variable.
If myVar is private then the first access method doesn’t work, so they are not equivalent.
–Being a function, we can alter what it returns by altering the function body. This enables us to modify the object returned without altering the classes that use the object. (about part 5, the singleton factory)
Except that that is the opposite of what you describe in part 5…
I describe in my comment above how to improve the function to allow this, by passing an interface rather than a class, and also apologise for not applying this in part 5.
However, I think you’ve made a good effort of trying to avoid the major shortcoming of Cairngorm, but I also think that you need to look more deeply at what, exactly, the problem really is…
As I said above - “I can see a very strong argument for creating an alternative to Cairngorm that uses DI throughout but it was not my intent here to advocate scrapping Cairngorm, I’m just looking to improve it.”
Cairngorm has the name of Adobe behind it and, like it or not, many developers will use it regardless of any shortcomings it has. That we can alter the way we manage the model within Cairngorm without having to alter or override any of the source code for Cairngorm itself provides one simple way to, perhaps, improve it by improving how people use it. This series of posts explores this idea.
richard | 26th May 2008 at 5:23 pm
I sort of think that we’ve come to the end of this argument, I don’t think I will convince you, and accept that if these ideas work for you then go for them.
However, the thing about Monostate needs to be cleared up:
The monostate uses private static variables. The scoping of these variables is the class itself. They are not accessible from outside this scope and hence are not global.
No matter how much you hide the global variable (in this case the state of the monostate class, which is kept in static variables, which makes it a collection of global variables) it will remain a global variable.
If you sprinkle your code with
new MyMonostate()instead ofMySingleton.getInstance()you will have tied your application to a concrete implementation and a global variable, regarless of the global variable appearing in disguise as multiple instances. Since all instances have the same state, which is global, they are nothing more than a facade to a collection of global variables.The monostate may not look like a global variable, and you can pretend that it isn’t, but you can’t change the design later to allow for multiple instances because your code acts like it was all the same instance. This is exactly the same problem as using a singleton by accessing it with it’s
getInstanceall over the place.If your code looks like this:
var myMonostate = new MyMonostate();
myMonostate.setTheThing(3);
//… snip …
var myMonostate = new MyMonostate();
var theThing = myMonostate.getTheThing();
Then, even though it looks like there’s no global variable, your code assumes that each and every instance of
MyMonostateshares state, and that a change to one changes the other, and that this state is accessible globally. This is a global variable, plain an simple.Theo | 26th May 2008 at 7:57 pm
I sort of think that we’ve come to the end of this argument, I don’t think I will convince you, and accept that if these ideas work for you then go for them.
I see only two things we haven’t agreed on -
1. Is the state in the Monostate global or not - we don’t appear likely to agree on that; you’re repeating your arguments and my response would be to repeat mine. The reality is, we probably don’t differ by much. I would agree that the static variables in a monostate create dependencies between each instance of the monostate class. But I don’t consider these private statics to fall under the definition of “global variable”. It’s probably just a semantic thing.
2. The second disagreement is harder to define. I think the real disagreement is over whether it’s worth trying to improve Cairngorm (and writing about it in a blog) when it’s architecture is designed around the idea of classes getting the state they want rather than having the state passed to them. I think it is, because a lot of people use Cairngorm. I don’t imagine we’ll agree on this either.
richard | 26th May 2008 at 9:27 pm
1.
It’s not so much semantics as a difference of ideas. I would define a global variable as something that is globally accessible and retains it’s state between accesses or invocations, if that is not exactly what a monostate is all about I don’t know what. You can call it what you want, but if it acts like a global, it is a global and I don’t think that hiding them (or renaming them) makes them less worse.
2.
Cairngorm is a bad architecture. It can be improved, but in the end you would have very little of Cairngorm left. This actually seems like what many do, they start using Cairngorm, realise some of the problems, rip that part out and replace it with something else, notice another problem and rip that out, and so on. In the end they have something they claim to have built using Cairngorm, but in reality it’s something built despite Cairngorm. I criticise Cairngorm quite a lot, and I always get the replies that “oh, no, of course we don’t use that part” or “of course we don’t use that, but the rest of Cairngorm is just fantastic”. What they mean when they say that is that Cairngorm forced them to think about the architecture of their application, made them realise the problems they were having (many because of Cairngorm) and this made their application better. I think that starting off with something that doesn’t need to be replaced along the way is a better way of doing it. However, if you learn something from the mistake of using Cairngorm, then you have at least learned something. Just make sure to learn to not make the same mistake twice.
You say that “Cairngorm has the name of Adobe behind it and, like it or not, many developers will use it regardless of any shortcomings it has”, which is the standard argument for Cairngorm. If you’re debating practicalities, then fair enough, you will have it easier find developers who have experience with it and you can slap a nice sticker on the product saying that it was built with Cairngorm and everyone will feel a little bit warm and fuzzy on the inside, it’s practical. However, if it’s architecture you want to discuss, then it just doesn’t cut it. I criticise Cairngorm because it’s an example of bad architecture, and using the “it’s backed by Adobe” makes it look like its bad architecture ok — how bad can it be when it’s backed by Adobe? If you want to defend Cairngorm (or global variables for that matter) from an architectural standpoint you have a a lot to prove.
Cairngorm is a little like the Basic family of programming languages: Basic is easy to understand and quick to learn, but you will pick up a lot of bad habits that in the end will make you shoot yourself in the foot once you try to do something more than a simple application. With Cairngorm you may not notice at first, but then the problems will start to show: dependency issues, hard to test, hard to reuse, hard to modularize, etc. Cairngorm takes many of the foundations of object oriented design and do the opposite. Programming to interfaces, why bother? Decoupling, no way. Modularity, fuck it.
I applaud your effort for writing this series, but I really think we need a more open discussion, one where Cairngorm isn’t a given, where Cairngorm can be criticised for what it is and where the standard response isn’t “but it’s backed by Adobe”. I realise that that wasn’t the intention of this series, but I think it could have been a better series if it wasn’t constrained by the architecture and mindset of Cairngorm.
Theo | 27th May 2008 at 8:07 am
Leave a Comment
XHTML: you can use these tags - <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>Subscribe to the comments via RSS Feed