Tell me more ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

There has been a lot of discussion lately about the problems with using (and overusing) Singletons. I've been one of those people earlier in my career too. I can see what the problem is now, and yet, there are still many cases where I can't see a nice alternative - and not many of the anti-Singleton discussions really provide one.

Here is a real example from a major recent project I was involved in:

The application was a thick client with many separate screens and components which uses huge amounts of data from a server state which isn't updated too often. This data was basically cached in a Singleton "manager" object - the dreaded "global state". The idea was to have this one place in the app which keeps the data stored and synced, and then any new screens that are opened can just query most of what they need from there, without making repetitive requests for various supporting data from the server. Constantly requesting to the server would take too much bandwidth - and I'm talking thousands of dollars extra Internet bills per week, so that was unacceptable.

Is there any other approach that could be appropriate here than basically having this kind of global data manager cache object? This object doesn't officially have to be a "Singleton" of course, but it does conceptually make sense to be one. What is a nice clean alternative here?

share|improve this question
I personally am yet to understand the who singleton issue, however ... what if the app grows much bigger? What if you suddenly want to go the multi-tiered route? If you have 1000 clients, then they will still send a whole bunch of requests before their caches fill up. Would it maybe make sense then to have a secondary tier, or a proxy? What if it goes down? I do not know what exactly you are building, but is sounds to me that you can get away with a singleton only for as long as the requirements do not change to the point that it does not help anymore. I suppose this applies to any design ... – Job Jan 27 '11 at 0:07
2  
What problem is the use of a Singleton supposed to solve? How is it better at solving that problem than the alternatives (such as a static class)? – Anon. Jan 27 '11 at 0:31
1  
@Anon: How does using a static class make the situation better. There is still tight coupling? – Loki Astari Jan 27 '11 at 0:33
1  
@Martin: I'm not suggesting it makes it "better". I'm suggesting that in most cases, a singleton is a solution in search of a problem. – Anon. Jan 27 '11 at 0:38
1  
@Aaronaught: Wait, since when can we not have static fields in a class? – Anon. Jan 27 '11 at 20:04
show 17 more comments

9 Answers

up vote 45 down vote accepted

It's important to distinguish here between single instances and the Singleton design pattern.

Single instances are simply a reality. Most apps are only designed to work with one configuration at a time, one UI at a time, one file system at a time, and so on. If there's a lot of state or data to be maintained, then certainly you would want to have just one instance and keep it alive as long as possible.

The Singleton design pattern is a very specific type of single instance, specifically one that is:

  • Accessible via a global, static instance field;
  • Created either on program initialization or upon first access;
  • No public constructor (cannot instantiate directly);
  • Never explicitly freed (implicitly freed on program termination).

It is because of this specific design choice that the pattern introduces several potential long-term problems:

  • Inability to use abstract or interface classes;
  • Inability to subclass;
  • High coupling across the application (difficult to modify);
  • Difficult to test (can't fake/mock in unit tests);
  • Difficult to parallelize in the case of mutable state (requires extensive locking);
  • and so on.

None of these symptoms are actually endemic to single instances, just the Singleton pattern.

What can you do instead? Simply don't use the Singleton pattern.

Quoting from the question:

The idea was to have this one place in the app which keeps the data stored and synced, and then any new screens that are opened can just query most of what they need from there, without making repetitive requests for various supporting data from the server. Constantly requesting to the server would take too much bandwidth - and I'm talking thousands of dollars extra Internet bills per week, so that was unacceptable.

This concept has a name, as you sort of hint at but sound uncertain of. It's called a cache. If you want to get fancy you can call it an "offline cache" or just an offline copy of remote data.

A cache does not need to be a singleton. It may need to be a single instance if you want to avoid fetching the same data for multiple cache instances; but that does not mean you actually have to expose everything to everyone.

The first thing I'd do is separate out the different functional areas of the cache into separate interfaces. For example, let's say you were making the world's worst YouTube clone based on Microsoft Access:

                          MSAccessCache
                                ▲
                                |
              +-----------------+-----------------+
              |                 |                 |
         IMediaCache      IProfileCache      IPageCache
              |                 |                 |
              |                 |                 |
          VideoPage       MyAccountPage     MostPopularPage

Here you have several interfaces describing the specific types of data a particular class might need access to - media, user profiles, and static pages (like the front page). All of that is implemented by one mega-cache, but you design your individual classes to accept the interfaces instead, so they don't care what kind of an instance they have. You initialize the physical instance once, when your program starts, and then just start passing around the instances (cast to a particular interface type) via constructors and public properties.

This is called Dependency Injection, by the way; you don't need to use Spring or any special IoC container, just so long as your general class design accepts its dependencies from the caller instead of instantiating them on its own or referencing global state.

Why should you use the interface-based design? Three reasons:

  1. It makes the code easier to read; you can clearly understand from the interfaces exactly what data the dependent classes depend on.

  2. If and when you realize that Microsoft Access wasn't the best choice for a data back-end, you can replace it with something better - let's say SQL Server.

  3. If and when you realize that SQL Server isn't the best choice for media specifically, you can break up your implementation without affecting any other part of the system. That is where the real power of abstraction comes in.

If you want to take it one step further then you can use an IoC container (DI framework) like Spring (Java) or Unity (.NET). Almost every DI framework will do its own lifetime management and specifically allow you to define a particular service as a single instance (often calling it "singleton", but that's only for familiarity). Basically these frameworks save you most of the monkey work of manually passing around instances, but they are not strictly necessary. You do not need any special tools in order to implement this design.

For the sake of completeness, I should point out that the design above is really not ideal either. When you are dealing with a cache (as you are), you should actually have an entirely separate layer. In other words, a design like this one:

                                                        +--IMediaRepository
                                                        |
                          Cache (Generic)---------------+--IProfileRepository
                                ▲                       |
                                |                       +--IPageRepository
              +-----------------+-----------------+
              |                 |                 |
         IMediaCache      IProfileCache      IPageCache
              |                 |                 |
              |                 |                 |
          VideoPage       MyAccountPage     MostPopularPage

The benefit of this is that you never even need to break up your Cache instance if you decide to refactor; you can change how Media is stored simply by feeding it an alternate implementation of IMediaRepository. If you think about how this fits together, you will see that it still only ever creates one physical instance of a cache, so you never need to be fetching the same data twice.

None of this is to say that every single piece of software in the world needs to be architected to these exacting standards of high cohesion and loose coupling; it depends on the size and scope of the project, your team, your budget, deadlines, etc. But if you're asking what the best design is (to use in place of a singleton), then this is it.

P.S. As others have stated, it's probably not the best idea for the dependent classes to be aware that they are using a cache - that is an implementation detail they simply should never care about. That being said, the overall architecture would still look very similar to what's pictured above, you just wouldn't refer to the individual interfaces as Caches. Instead you'd name them Services or something similar.

share|improve this answer
2  
+100 if I could. This is probably the best explanation for this sort of design that I've ever read. – Michael K Jan 27 '11 at 20:20
Wow, just... Wow. – Madara Uchiha Apr 9 '12 at 18:55
First post I have ever read which actually explains DI as an alternative to global state. Thanks for the time and effort put into this. We are all better off as a result of this post. – MrLane Jan 23 at 1:11

In the case you give, it sounds like the use of a Singleton is not the problem, but the symptom of a problem - a larger, architectural problem.

Why are the screens querying the cache object for data? Caching should be transparent to the client. There should be an appropriate abstraction for providing the data, and the implementation of that abstraction might utilize caching.

The issue is likely that dependencies between parts of the system are not set up correctly, and this is probably systemic.

Why do the screens need to have knowledge of where they get their data? Why are the screens not provided with an object that can fulfill their requests for data (behind which a cache is hidden)? Oftentimes the responsibility for creating screens is not centralized, and so there is no clear point of injecting the dependencies.

Again, we are looking at large-scale architectural and design issues.

Also, it is very important to understand that the lifetime of an object can be completely divorced from how the object is found for use.

A cache will have to live throughout the application's lifetime (to be useful), so that object's lifetime is that of a Singleton.

But the problem with Singleton (at least the common implementation of Singleton as a static class/property), is how other classes that use it go about finding it.

With a static Singleton implementation, the convention is to simply use it wherever needed. But that completely hides the dependency and tightly couples the two classes.

If we provide the dependency to the class, that dependency is explicit and all the consuming class needs to have knowledge of is the contract available for it to use.

share|improve this answer
There is a gigantic amount of data that certain screens might need, but don't necessarily need. And you don't know until user actions have been taken which define this - and there are many, many combinations. So the way it was done was to have some common global data that's kept cached and synced in the client (mostly obtained at login), and then subsequent requests build up the cache more, because explicitly requested data tends to be re-used again in the same session. The focus is on cutting down on requesting to the server, hence the need for a client side cache. <cont> – Bobby Tables Jan 27 '11 at 0:26
<cont> It essentially IS transparent. In the sense that there is a callback from the server if certain required data isn't cached yet. But the implementation (logically and physically) of that cache manager is a Singleton. – Bobby Tables Jan 27 '11 at 0:27
3  
I am with qstarin here: The objects accessing the data should not know (or need to know) that the data is cached (that is an implementation detail). The users of the data merely ask for the data (or ask for an interface to retrieve the data). – Loki Astari Jan 27 '11 at 0:30
The caching IS essentially an implementation detail. There is an interface through which data is queried, and the objects getting it don't know if it came from the cache or not. But underneath this cache manager is a Singleton. – Bobby Tables Jan 27 '11 at 0:52
1  
@Bobby Tables: then your situation isn't as dire as it seemed. That Singleton (assuming you mean a static class, not just an object with an instance that lives as long as the app) is still problematic. It's hiding the fact that your data providing object has a dependency on a cache provider. It is better if that is explicit and externalized. Decouple them. It is essential for testability that you can easily substitute components, and a cache provider is a prime example of such a component (how often is a cache provider backed by ASP.Net). – qes Jan 27 '11 at 3:24
show 2 more comments

Its not global state per se that is the problem.

Really you only need to be worried about global mutable state. Constant state is not affected by side affects and thus is less of a problem.

The major concern with singleton is that it adds coupling and thus makes things like testing hard(er). You can reduce the coupling by getting the singleton from another source (eg a factory). This will allow you to decouple the code from a particular instance (though you become more coupled to the factory (but at least the factory can have alternative implementations for different phases)).

In your situation I think you can get away with it as long as your singleton actually implements an interface (so that an alternative can be used in other situations).

But another major draw back with singletons is that once they are in-place removing them from code and replacing them with something else becomes a real hard task (there is that coupling again).

// Example from 5 minutes (con't be too critical)
class ServerFactory
{
    public:
        // By default return a RealServer
        ServerInterface& getServer();

        // Set a non default server:
        void setServer(ServerInterface& server);
};

class ServerInterface { /* define Interface */ };

class RealServer: public ServerInterface {}; // This is a singleton (potentially)

class TestServer: public ServerInterface {}; // This need not be.
share|improve this answer
That makes sense. This also makes me think that I never really abused Singletons, but just started doubting ANY use of them. But can't think of any outright abuse that I've done, according to these points. :) – Bobby Tables Jan 27 '11 at 0:17
(you probably mean per se not "per say") – nohat Jan 27 '11 at 0:28
1  
@nohat: I am native speaker of the "Queens English" and thus reject anything French looking unless we make it better (like le weekend oops that's one of ours). Thanks :-) – Loki Astari Jan 27 '11 at 0:37
5  
per se is latin. – Anon. Jan 27 '11 at 0:40
1  
@Anon: OK. That's not so bad then ;-) – Loki Astari Jan 27 '11 at 0:44

I wrote a whole chapter on just this question. Mostly in the context of games, but most of it should apply outside of games.

tl;dr:

The Gang of Four Singleton pattern does two things: give you convenience access to an object from anywhere, and ensure that only one instance of it can be created. 99% of the time, all you care about is the first half of that, and carting along the second half to get it adds unnecessary limitation.

Not only that, but there are better solutions for giving convenient access. Making an object global is the nuclear option for solving that, and makes it way to easy to destroy your encapsulation. Everything that's bad about globals applies completely to singletons.

If you're using it just because you have a lot of places in code that need to touch the same object, try to find a better way to give it to just those objects without exposing it to the entire codebase. Other solutions:

  • Ditch it entirely. I've seen lots of singleton classes that don't have any state and are just bags of helper functions. Those don't need an instance at all. Just make them static functions, or move them into one of the classes that the function takes as an argument. You wouldn't need a special Math class if you could just do 123.Abs().

  • Pass it around. The simple solution if a method needs some other object is to just pass it in. There's nothing wrong with passing some objects around.

  • Put it in the base class. If you have a lot of classes that all need access to some special object, and they share a base class, you can make that object a member on the base. When you construct it, pass in the object. Now the derived objects can all get it when they need it. If you make it protected, you ensure the object still stays encapsulated.

share|improve this answer
Can you summarize here? – NickC Jan 27 '11 at 19:55
Done, but I still encourage you to read the whole chapter. – munificent Jan 27 '11 at 21:20
2  
another alternative: Dependency Injection! – Brad Cupit Feb 2 '11 at 2:12

A singleton is not in a fundamental way bad, in the sense that anything design computing can be good or bad. It can only ever be correct (gives the expected results) or not. It can also be useful or not, if it makes the code clearer or more efficient.

One case in which singletons are useful is when they represent an entity that really is unique. In most environments, databases are unique, there really only is one database. Connecting to that database may be complicated because it requires special permissions, or traversing through several connection types. Organizing that connection into a singleton probably makes a lot of sense for this reason alone.

But you also need to be sure that the singleton really is a singleton, and not a global variable. This matters when the single, unique database is really 4 databases, one each for production, staging, development and test fixtures. A Database Singleton will figure out which of those it should be connecting to, grab the single instance for that database, connect it if needed, and return it to the caller.

When a singleton is not really a singleton (this is when most programmers get upset), it's a lazily instantiated global, there's no opportunity to inject a correct instance.

Another useful feature of a well designed singleton pattern is that it is often not observable. The caller asks for a connection. The service that provides it can return a pooled object, or if it's performing a test, it can create a new one for every caller, or provide a mock object instead.

share|improve this answer

First question, do you find a lot of bugs in the application? perhaps forgetting to update cache, or bad cache or find it hard to change? (i remember an app wouldnt change sizes unless you changed the color too... you can however change the color back and keep the size).

What you would do is have that class but REMOVE ALL STATIC MEMBERS. Ok this isnt nessacary but i recommend it. Really you just initialize the class like a normal class and PASS the pointer in. Don't frigen say ClassIWant.APtr().LetMeChange.ANYTHINGATALL().andhave_no_structure()

Its more work but really, its less confusing. Some places where you shouldnt change things you now cannot since its no longer global. All my manager classes are regular classes, just treat it as that.

share|improve this answer

Use of the singleton pattern that represents actual objects is perfectly acceptable. I write for the iPhone, and there are lots of singletons in the Cocoa Touch framework. The application itself is represented by a singleton of the class UIApplication. There's only one application that you are, so it's appropriate to represent that with a singleton.

Using a singleton as a data manager class is okay as long as it's designed right. If it's a bucket of data properties, that's no better than global scope. If it's a set of getters and setters, that's better, but still not great. If it's a class that really manages all interface to data, including perhaps fetching remote data, caching, setup and teardown... That could be very useful.

share|improve this answer

My main problem with the singleton design pattern is that it is very difficult to write good unit tests for your application.

Every component that has a dependency to this "manager" does so by querying its singleton instance. And if you want to write a unit test for such a component you have to inject data into this singleton instance, which may not be easy.

If on the other hand your "manager" is injected into the dependent components through a constructor parameter, and the component doesn't know the concrete type of the manager, only an interface, or abstract base class that the manager implements, then a unit test could supply alternate implementations of the manager when testing dependencies.

If you use IOC containers to configure and instantiate the components that make up your application, then you can easily configure your IOC container to create only one instance of the "manager", allowing you to achieve the same, only one instance controlling global application cache.

But if you don't care about unit tests, then a singleton design pattern can be perfectly fine. (but I wouldn't do it anyway)

share|improve this answer

IMO, your example sounds okay. I'd suggest factoring out as follows: cache object for each (and behind each) data object; cache objects and the db accessor objects have the same interface. This gives the ability to swap caches in and out of the code; plus it gives an easy expansion route.

Graphic:

DB
|
DB Accessor for OBJ A
| 
Cache for OBJ A
|
OBJ A Client requesting

DB accessor and cache can inherit from the same object or duck type into looking like the same object, whatever. So long as you can plug/compile/test and it still works.

This decouples things so you can add new caches without having to go in and modify some Uber-Cache object. YMMV. IANAL. ETC.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.