Project of AEREZONA DEVELOPERS. Contact Us at: +92-300-3308001 email at: [email protected]
HomeTech NewsPatterns in software development: advantages and disadvantages of the singleton pattern

Patterns in software development: advantages and disadvantages of the singleton pattern

Published on

- Advertisement -

The singleton pattern is considered a controversial design pattern. It is therefore worth taking a look at the advantages and disadvantages as well as possible alternatives.

 

The Singleton pattern is considered the most controversial design pattern from the book “Design Patterns: Elements of Reusable Object-Oriented Software” (Design Pattern). In my last article “Patterns in software development: The singleton pattern” I introduced the classic singleton pattern and the so-called Meyers singleton. Now I would like to go into the advantages and disadvantages of the singleton in more detail – and present possible alternatives.

- Advertisement -

 

“Thread-safe Initialization of a Singleton” is my most-read article to date. It has been read more than 300,000 times and I have received many comments on it. Then I have asked about Twitter in the community, who uses the singleton pattern. From the 150 or so responses to my question, the picture that emerged is not as clear as I expected: 59 percent use the singleton pattern, but 41 percent don’t.

 

The comments I received on the Singleton pattern can be summed up in two statements:

  • I don’t use the singleton because it’s an anti-pattern.
  • I only use the singleton selectively.
- Advertisement -

From my daily work, I know numerous developers who often use the singleton pattern. Therefore, I suspect that this group has not yet spoken at all in the discussion. If I include this “silent” faction in the poll results, up to 80 percent of software developers are likely to use the singleton pattern.

So let me dive deeper into the singleton pattern and analyze its pros and cons.

I want to start positively:

  • Global access point
- Advertisement -

A singleton is a disguised global object that offers a global access point. As a global object, a singleton can be accessed from anywhere in the program, but it cannot be modified from anywhere. It can only be changed within the singleton. So it is a means to protect global objects.

  • Unique entity model

Modeling real entities helps to think about your own program. In reality, we often have singletons like registration offices, global timers, or offices for identities. By modeling you achieve a better match between your program abstraction and reality. This match will help you and your client better understand the program.

  • The Static Initialization Order Fiasco

In my last article, I detailed the Static Initialization Order fiasco. It means that you have no guarantee of the order in which static elements are initialized and destroyed in different translation units. The “Design Patterns: Elements of Reusable Object-Oriented Software” based implementation of the singleton pattern has this problem, but the Meyers singleton overcomes it.

  • competition

The Meyers singleton also overcomes the concurrency problem of the classic singleton implementation. The Meyers singleton is based on a local, static variable. Since C++98, static variables with local scope are initialized lazy and since C++11 even thread-safe.

  • Used too often

The singleton pattern was often used even though it was inappropriate and a simple object would have been a better solution. This was mainly due to the fact that software developers want to prove that they have understood the classic design pattern and thus use the supposedly simplest pattern. In all honesty, we can’t blame the singleton pattern for being abused here.

  • Hidden Dependencies

This is my main criticism: a singleton introduces a hidden dependency, thereby undermining the testability of the code. Let’s consider the following code snippet:

 

void func() {
   ...
   DataBase::getInstance().update("something");
   ...
}

 

The call DataBase::getInstance().update("something") creates a hidden dependency. The caller of the function func receives a notification that a database is being called up internally. What are the consequences? The code is no longer a unit and cannot be tested in isolation. Instead of a unit test, only a system test that includes the database can be carried out. In the end, there are always two entities to be tested: the code of the function func and the database.

Unit tests should

  • have no external dependencies.
  • to be fast.
  • have no side effects.

We cannot blame the singleton pattern for the hidden dependency. This is just bad software design. A better structured code could look like this:

 

func(DataBaseSingleton::getInstance());

...

void func(DataBase& db) {
   ...
   db.update("something");
   ...
}

 

Use the DataBase in the interface of the function. Now there are no more hidden dependencies. The function can be executed quickly and without side effects. Now it’s a unit and therefore also unit-testable. Why?

turn off DataBase an interface and provide at least two implementations. One is the original singleton DataBaseSingleton and the other is a mock object: DataBaseMock. That DataBaseMock mimics the behavior of DataBaseSingleton and can as DataBase be used. That DataBaseMock is fully deterministic and does not involve any dependencies.

 

func(DataBaseMock::getInstance());

...

void func(DataBase& db) {
   ...
   db.update("something");
   ...
}

 

It seems pointless to argue for or against the singleton pattern. Each pattern has its pros and cons, and this is especially true for the singleton pattern. You should therefore weigh up whether the advantages outweigh the disadvantages in the specific case. You should also use the Meyers singleton where appropriate, and the singleton should be part of your function signature.

To conclude my discussion of the pros and cons of singletons, I would like to recommend two critical articles on the singleton pattern by Arne Mertz and Jonathan Boccara:

  • Simplify C++ by Arne Mertz: Singletons: What’s the Deal?
  • Fluent C++ by Jonathan Bocara: The Issues With the Singletons and Hot to Fix Them

Please email me at [email protected] and I may write another article on this subject.

Until now I haven’t written about the alternatives to the singleton pattern. In my next article, I’ll introduce two more patterns: the Monostate pattern (aka the Borg idiom) and Dependency Injection.

 

Modern C++ mentoring

Get the invitation to the one-hour presentation of my mentoring program “Fundamentals for C++ Professionals” including Q&A

  • First: 2022-10-03; 9pm (CEST)
  • Second: 2022-10-10; 9 am (CEST)
- Advertisement -

Latest articles

NATO is turning its focus to China. Here’s what that means.

The NATO alliance has strengthened its eastern flank over Russia's war on Ukraine but...

The EU backs off a bit on its crusade on derivatives clearing

It will not put an end to the equivalence with the United Kingdom, but...

More like this