Follow-up on this question: Singletons: good design or a crutch?

It is true, that using singletons can make testing harder, and bugs can hide behind them. GoF defines singleton to use when:

  • Global access needed AND
  • Single instance needed

There are too many problems that can be solved with only one of the above points, but not many that requires both.

My question is:
When is it reasonable to use the singleton pattern?

4 Replies 4

Currently, I have a system with a server, and multiple clients (clients can come and go). There is a single configuration that lists all the expected clients with their settings. For clients that are not in that list, a default empty settings should be sent.

Therefore I'm using singleton pattern for the default settings, because each not-listed client shares the same settings, and should access it when connects and ask for their settings. Default settings defined as a constant.

Let's check the singleton criteria:

  • Single instance: is required for memory efficiency (note, I keep the singleton a constant)
  • Globally accessible: There are 8 paths that needs access to it. It looks better than passing a reference in case the client is not in the list
  1. Arguably this can hugely depend on the language/stack you are working with and general approaches to the development. For example when building one-off tool it's just fine to save time.

  2. I would argue that it's fine to have a singleton's but you might want to still abstract over them for example using some kind of Inversion of Control/Dependency injection. I.e. you don't use the singleton directly but pass the instance (possibly abstracted via some interface) to the user. Otherwise you have a big risk of hugely reducing the testability of the application. Arguably almost all of the "global access" cases can be refactoried into some kind of injection/passing dependency pattern.

So to sum up - this is about the trade off analysis - how long you will be maintaining the application and how hard it would be to provide the singleton via some abstraction.

In our code base, I have instrumented properly singletons so that they can be used in unit tests without any problem. I don't really understand why apparently I am the only one who have done such an implementation, as to me the needs seems rather fundamental.

We have a BaseSingleton<T> template class. Among other things, the getter function will create atomically the underlying object if not already created and register the pointer to the newly created object inside an array of pointers. Each object has a reference counter. At the end of each unit test (we are using CATCH framework), registered singletons are released in reverse order of creation. It is possible that during singleton destruction phase, some other singletons are created again. In case of resurrection, those resurrected singletons are released again until none remain.

By the way, I implemented a similar feature for threads. In our framework, spawn threads are automatically stopped at the end of each unit test. In this case also, resurrected thread can happen, and we try again stopping those.

Given the instrumentation of BaseSingleton<T>, we are using it a lot in our code base, even when only second point yields true (Single instance needed), without the need of global access. It happened that because of the instrumentation, it actually makes things often more testable with a singleton than a manually created object, because the lifetime of the object is handled automatically.

For completeness, the GoF book defines Singleton to use when:

(page 127)

  • there must be exactly one instance of a class, and it must be accessible to clients from a well-known access point.

  • when the sole instance should be extensible by subclassing, and clients should be able to use an extended instance without modifying their code.

Most people miss the second point.

Your Reply

By clicking “Post Your Reply”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.