views:

669

answers:

9

I have a few classes in a project that should be created only once.

What is the best way to do that?,

  1. They can be created as static object.
  2. Can be created as singleton
  3. Can be created as global.

What is the best design pattern to implement this?

I am thinking of creating all classes as singleton, but that would create lot of singletons. Is it good programming practice to have lot of singletons?

What are the pros and cons for using singletons?

+13  A: 

Take a look at Steve Yegge's blog post about this - Singleton Considered Stupid

David Hodgson
Okay I just gone through the blog..I am facing similare kind of problem having classes like RegistryManager,FileManager,DataBaseManager etc and each class shoud be initiliazed only once and different threads can set states of these classes which should be visible to all of them.
Alien01
Thank you for the link. Thats a nice summary, and saved me quite a few words. Singletons at times are a unavoidable evil, but they should be avoided when possible, especially if they are mutable.
Yann Ramin
A: 

In programming there are no silver bullets. Making every class a singleton will not magically make your code "better". Singletons are a tool for that solve a specific problem I studying more about singletons.

pygorex1
+5  A: 

If they only need to be created once, that doesn't mandate they should be singletons.

  • If X is a singleton, it's implied there is one instance.
  • If X has one instance, that doesn't mean it should be a singleton.

Use a singleton if you require there be only one instance of the class, and that it be globally accessible. In your case, simply only needing one isn't reason enough. Globals are bad, singletons are glorified globals.

Most often, you don't need them. You'll see it a lot in bad code because of the very mentality: I only need one, that must mean I should make it singleton! (Wrong) For example, I've finished the technical design of the most powerful game engine I've ever done to date. It has 2 singletons, for memory and threading. A very large project, and I only have two!

More context would help us give you better information.

GMan
Agreed, although I wouldn't call singletons "glorified globals". They're globals with an additional unnecessary, and often crippling, design problem thrown in. If you need something to be globally accessible, make it a global, not a singleton.
jalf
@jalf: I don't think I agree with that. Singletons can be lazily created, to avoid the static fiasco.
GMan
And then you're left with a much more complicated implementation to achieve exactly the functionality that a plain global would've provided. Just because it is possible to work around the problems a singleton creates doesn't mean that it's a better solution than not creating the problems in the first place. What benefit does a singleton have over a global?
jalf
@jalf, Like above, globals don't have a set initialization order. Singletons are also classes, which have private details and functions. (A global would mean more global variables, while a singleton is technically just one variable.) I'm not sure I understand what problems a singleton has over a global. :) My singleton is simple: `singleton<foo>::reference().foo_bar();`, and is non-intrusive.
GMan
The problem a singleton has over a global is that *you can only create one instance*. What when you want to test it? Good luck instantiating it in your test case setup. What when you find out that oops, you *did* need two after all. It's a silly and premature constraint to put on your code that "only one instance can ever be created". If you want lazily instantiated globals, then implement those, nothing is stopping you. But don't bother preventing multiple (non-global) instantiations of the class.
jalf
@jalf, But if I need to test it, I just create an instance: `foo f;` It's non-instrusive. In my two cases, there *must* be only one and globally accessible instances of those classes, because they are system-wide., not a premature constraint. The thing is, in my case (so maybe not relevant to , I need to be able to change where the instance of my singleton(s) come from, because I have different "processes" (dynamic-libraries) that would normally make their own. It's easy: `singleton<foo>::instance(some_pointer)`, so any further accesses use that instance of `foo` instead.
GMan
Though that would be easy to implement as a global function too... FUU- now my fairness bit is kicking in. I think sometime I shall switch singleton->global and see what the differences are.
GMan
If you can just create an instance, it's not really a singleton though. If you remove that constraint and make it possible to instantiate the object at will, then it's not a singleton, just a global, and we agree. ;)
jalf
As for the system-wide constraint, that's not true. You have a constraint that exactly one instance is globally accessible, and represents the "official" system-wide state. But that doesn't in itself mean that other, local instances can not be meaningful. It is premature to prevent instantiation of other instances.
jalf
@jalf, I should mention I'd have to comment a parameter out of the constructor and make it copyable to just make an instance, but ok-ok I see. So then what I want then is a globally accessible instance of a certain class... a global variable. :O Since `singleton` *does* already handle the "make it global part", would it be worthwhile to just take out the non-copyable and single-instance stuff and change `singleton` to `global`? :) To help out with my per-process instance changing and initialization. Good-bye, singleton.
GMan
"I've finished the technical design of the most powerful game engine I've ever done to date." Care to elaborate? Or have a link?
StackedCrooked
@Stacked: It's all private, sorry. :S
GMan
+3  A: 

Singletons have a few problems -- they're hard to test, hard to replace, and hard to extend. There's usually a better way.

Kaleb Brasee
+1  A: 

A singleton is effectively global state. If you're going to create lots of singletons you're going to create lots of global state, only in won't necessarily look like global state.

This makes it hard to do things like buid unit tests, provide mock classes and reuse code because its really easy to oouple the current state to a function. i.e. function foo is only valid when class X is in state Z, otherwise it doesn't work.

It's also problematic to build a thread safe singleton correctly.

Singletons can be good for coordinating access to a resource, particularly one that doesn't have much state and is expensive to construct.

So why do you think you need lots of singletons? you may get better responses if you ask about your problem domain and what issue you are hitting.

Rick
+4  A: 

I suggest you look at some of the videos and articles that Miško Hevery of Google has done. First a video: "Clean Code Talks: Global State and Singletons" and his blog.

The general concensus is that Singletons are OK in a few rare instances, for example logging, but in most other situations you want to use dependency injection. Singletons make it harder to test your code and they hide dependencies so that your classes cannot be instantiated easily in isolation.

Mike Weller
+3  A: 

One of my favourite articles on the singleton is Singletons are Pathological Liars by Miško Hevery. Essentially, they encourage "hidden" behaviour that is very hard to learn and test.

Greg Hewgill
+1  A: 

There are projects where you can't practically avoid using globals. All kinds of service locators or dependency-injection frameworks still rely on global (not always static variable, but always global of some sort) storage of objects.

However, singletons are a sign of a problem:

  • First, singleton as a canonical pattern doesn't go well with interfaces and abstraction. It can be fixed though - accessing it through factory.
  • Worse, singletons are inflexible - they don't have any means of identifying object beyond its type. ( Well, in C++ they do through templates, but it's a different story). In that sense they are actually worse than static variables. In the long run it pays off using a framework where many instances of the same type can be accessed.
  • And most importantly, lots of singletons means lots of distant relationships between objects. Which means your system is probably more complex than it needs to be and will be much harder to develop, test and manage. Simply switching to locators or DI won't help there, it's a matter of underlying design principles.
ima
+1 For DI hype not being the solution.
rama-jka toti
DI is perpendicular to this issue. DI is exactly that - injecting dependencies into objects through factories. It tells nothing about nature of those dependencies. The confusion in other answers here is probably from the fact that most all DI frameworks include dynamic configuration and service locator. Both of those can be used without DI, and DI technically can be used without them.
ima
Think of DependencyManager.Register(Singleton::Instance())
ima
A: 

To use singleton pattern in your project should be a well thought out and careful design decision, because its a one way track with very little scope for backtracking. I have practically used it in one of my project for a commercial product in a multithreading environment and faced multitude of problems. But this doesn't mean it's an untouchable pattern. The point is anything which can be achieved with singleton can be achieved without it, with less hassles and complexity. For more on this you can track this question I asked some months back. It has interesting links and insight into the singleton pattern

rocknroll