I’ve searched about this here and on StackOverflow and found some differences between the two.
But I’m still not sure in what cases one would prefer a Singleton, and in what cases one would choose to use a static class.
(In languages which don’t support ‘static classes’, like Java, I’m obviously referring to classes containing only static methods and fields).
Please give me concrete examples of cases where you would pick each one, and explain why.
3
A case where a static class might be a good idea is when you want to collect related pieces of functionality, but you don’t need to have any internal state in any object. An example could be the Math class in Java. It contains a whole bunch of related functions that are accessed outside the context of any specific object instance. I’ve done similar things where a set of common utility functions that are used in multiple places in an application are grouped together into a single utility class.
A singleton is used when you do want an actual object (with its own internal state and everything), and you want to limit your system to exactly one instance of that object. This might be useful if you have some kind of shared resource, such as a database, an in-memory cache, or maybe some specialized piece of hardware like a robotic arm. Many parts of your program might want to use this resource and you might want to have all access to the resource go through a single point. A singleton isn’t always the only way to handle these situations, but it’s one of the few places I think a singleton might be a good choice.
11
-
Avoid the Gang of Four Singleton pattern, for reasons cited in the other answers. Mainly it is an anti-pattern based on difficulties it creates for testing.
-
Factory and Dependency Injection made Singleton obsolete. The best answer is to use a Factory that decides whether to instantiate one instance, or many, of a given class. That way, the class and its clients aren’t responsible for its singleton status — that becomes a transparent concern managed by the Factory.
-
Dependency injection frameworks like Spring do that for you out of the box (e.g. Spring beans are singletons unless you specify otherwise).
-
Purely static classes are problematic for both testing and using OO concepts. I’ve seen teams with an irresistible urge to make everything static and final, and the question becomes, why aren’t they just writing C code?
-
If your static class has side effects, then it should not be static. That means, if it’s managing shared state, or if it’s changing the state of parameters, then it should be a regular class where the Factory hands out a single shared instance. A purely static class that manages shared state becomes a really hard problem for testing.
-
A purely static class also creates hard, compile-time dependencies on that particular class, which really compromises the extend-ability and test-ability of your code. Seems like you’d want to reserve that for something eternal and unchanging, with no side effects, like math formulas.
So the answer is, don’t write classes as singletons, but rather move that decision into your Factory. And in an OO language, static classes miss some of the most important design aspects of the language and complicate testing. Again, you can use worker classes with specific semantics to bundle those up and have them generated by your Factory.
3
Singletons objects made so there can only be 1 instance at any given time and can be used application wide.
Objects that handle stuff like connection pools are a good candidate to be Singletons;
- You only want 1 instance in the entire application
- you must be able to access it from different parts of the application
- the data it holds has to be persisted even when no other objects are currently pointing to it (handy when you want to reuse objects that are expensive to initialize).
A class filled with only static methods is not something that’s usually meant to be initialized like an object. It’s more like a wrapper for the static methods in it.
An example of this that I use frequently is a utility class with methods that do repetitive tasks that take parameters, does a calculation with them/formats them/etc. and then returns the result, without using any external (or at least no non-static) fields or methods.
I never initialize a utility class, I just use the static methods in it for all repetitive methods.
This is just how I tend to use Singletons and static (method filled) classes, not sure if it confirms to any “official” standards…
4