Possible Duplicate:
What is so bad about Singletons?
It's understandable that many design patterns can in some cases be abused, and like mom always said: "Too much of a good thing isn't always good!"
I'm noticing that these days, I'm using Singletons a lot, and I'm worried that I might be abusing the design pattern myself, and running deeper and deeper into a bad-practice kind of habit.
We're developing a Flex application that has a quite a large hierarchical data structure kept in memory while the user works on it. The user can load, save, change and refresh the data on demand.
This data is centralized by means of a Singleton class, which aggregates a couple of ArrayCollections, Arrays, value objects and some other native member variables exposed via getters and setters.
To get a reference to our data from anywhere in the application, we do the whole Model.getInstance() method type of thing, that I'm sure everyone is familiar with. This ensures that we always get our hands on the same copy of data, since when we designed, we said that only once instance is allowed to exist during the application lifetime.
From this central data repository, it's then easy for us to for example, dispatch property changed events, and can have multiple UI components that reference the central data, update their displays to reflect the data changes that have occurred.
So far, this approach has been effective and proven very practical to our circumstances.
I'm finding however, that I'm a little overeager when creating new classes. Questions like should a class be a Singleton, or should it rather be managed some other way, like maybe using a factory for example, tend to sometimes become a bit difficult, with a bit of uncertainty.
Where do I draw the line with singletons? Is there a good guideline for deciding when to use Singletons and when to stay away from them.
Also, can anyone recommend a good book on design patterns?
In my opinion the use of Singletons directly signals a design flaw. The reason is simply that they allow one to bypass the normal object creation and destruction mechanisms built into C++. If an object needs a reference to another object, it should either pass in a reference to it upon construction or create a new instance of it internally. But when you use a singleton you're explicitly obfuscating the creation and teardown cycle. A related problem is that it is extremely difficult to control the lifetime of a singleton. As a result, many packages which include generic singleton implementations also include clunky object lifetime managers and the like. Sometimes I wonder if these don't exist simply to manage the singletons.
Basically, if you need to use an object in many places, it should be created explicitly at the highest common point in the stack and then passed down via reference to everybody who uses it. Sometimes people use Singletons because they have problems passing multiple args to new threads, but don't fall for this, explicitly define your thread args and pass them to the new thread in the same manner. You'll find that your program flows much cleaner and there are no nasty surprises due to static initialization dependencies or erroneous teardown.
Singletons are not "that bad". If you have a lot of related Singletons and you can replace/consolidate a number of them using a Factory, without losing anything you care about, then that's when you should so do.
As to books, well, there's kind of a canon.
Software developers seem to be pretty evenly split into two camps, depending on whether they favor an idealistic coding style or a pragmatic one:
Personally, I favor the pragmatic approach. Sometimes it makes sense to break the rules, but only if you really understand what you are doing and are willing to accept the associated risks. If you can answer "yes" to the questions below regarding your specific use case, the singleton pattern can yield some practical benefits.
Singletons don't kill programs, programmers kill programs.
Like any programming construct, when used appropriately, you will not shoot yourself in the foot.
The books recommended are fine, but they don't always give enough background that comes with experience on when you might make the choice to use Singleton.
That experience only comes when you've found Singleton is a bad choice when you need to have multiple instances, and all of a sudden, you've got a lot of trouble injecting the object references everywhere.
Sometimes it's better to go ahead and have the object references in place, but the fact that you are using Singleton at all does help to identify the scope of the problem you would face if you had to refactor it to a different design. Which I believe is a very good thing: i.e. just having a class at all (even if poorly designed) gives some ability to see the effects of a change to the class.
We have started a project where we are basically facing the same question, that is, how to access the model, and especially its root element. The project is not a Flex app, but a play! web app, but that doesn't matter really.
Having a single object unique in the system is fine, the problem is how to access it. So the debate about singleton is related to the notion of dependency injection (DI), and how to obtain objects.
The main arguments for DI are the following:
Possible approaches for DI are (see the classic article from Fowler):
Under this perspective, the singleton pattern is just a kind of service locator, e.g.
Model.getInstance()
.But to provide maximum flexibility in face of future changes, the reference to the unique object should be passed around as much as possible, and obtained with
Model.getInstance()
only when necessary. This will also yield cleaner code.Singletons are certainly not bad. They have their uses, some of them very good. Singletons do tend to be overused by inexperienced developers as it's often the first design patten they learn about, and it's fairly simple, so they chuck it around all over the place without thinking about the implications.
Every time you want to use a singleton, try to consider why you are doing it, and what are the benefits and negatives of using this pattern.
Singletons do effectively create a global accessible set of 'stuff' (either data or methods) and I think most people would agree that using too many global variables is not a great idea. The whole point of classes and object orientation is to group things into discrete areas rather than just chucking everything into one massive global space.
One of the 'patterns' I find I tend to prefer over singletons is to pass needed objects down from the top. I create them once during my apps initialization phase, and a pass them down through all the objects that need access to them. It mimics the 'single-creation' part of a singleton pattern, but without the 'global' part.
The whole point of a singleton is that it's for objects where only 1 should ever exist. You mention a data control set of classes. Perhaps consider that actually, there are cases where an app might want to create 2 sets of data control classes, so perhaps enforcing a singleton on this isn't quite right. Instead, if you created these data classes on app init, and passed them down, you would be only creating 1 set as that is what you current app requires, but you leave open the possibility that at some point, if you need a second set you can easily create them. Also, should data control classes really be accessibly globaly from anywhere in the app. I think not, instead they should probably be only accessible from a lower level data access layer.
Some people have recommended the GOF book. I would say, yes that is a great book, but first try and find a book on general architecture first, read about 2/3/n-tier design, encapsulation, abstraction, and these kind of principles first. This will give you a more solid base with which to understand the appropriate usage of the patterns the GOF talk about.
[Edit: The other time that a singleton variant can be useful is when you want a single access point to something, but the implementation detail might actually be more than one thing. The caller doesn't need to know, that under the covers their request for the singleton object is actually resolved against several available objects and one is returned. I'm thinking of something like a thread pool here, where the use goes, hey, just get me a thread, I need 1, but I don't care which one]