So far, I have discussed in my previous posts the Singleton Pattern, and its pros and cons. One question is still open: What alternatives for the Singleton Pattern are available? Today, I write about the Monostate Pattern and Dependency Injection.
I want to start this post with the Monostate Pattern.
The Monostate Pattern
The Monostate Pattern is similar to the Singleton Pattern and quite popular in Python. While the Singleton Pattern guarantees that only one instance of a class exists, the Monostate Pattern ensures that all instances of a class share the same state. The Monostate Pattern is also known as Borgidiom, because the Borgs in the Star Trek series share a common memory.
In the Monostate Pattern, all data members are
static. Consequentially, all instances of the class use the same data. The member function to access the data are non-
static. Users of the instances are unaware of the singleton-like behavior of the class.
Each instance of the class
Monostate shares the same state:
You probably think about Dependency Injection in the first place when you search for the alternative for the Singleton Pattern.
The Singleton Pattern has serious drawbacks that I described in the previous post “The Singleton: Pros and Cons”, Consequentially, the Singleton Pattern would probably not be part of a reprint of the book “Design Patterns: Elements of Reusable Object-Oriented Software”. Instead, Dependency Injection is a highly likely future candidate.
The key idea of Dependency Injection is that an object or function (client) receives the other service it depends on. Therefore, the client is not aware of the construction of the service. The client is fully separated from the service that is injected by an injector. This is in contrast to the Singleton Pattern, where the client creates the service if needed.
Dependency Injection is a form of inversion of control. Not the client creates and calls the service, but the injector injects the service into the client.
In C++, three types of Dependency Injection are typically used:
- Constructor injection
- Setter injection
- Template parameter injection
I use constructor injection and setter injection in the following program
cl requires logger functionality. First, the logger
SimpleLogger is injected using the constructor (line 1), afterwards the logger is replaced with the more powerful logger
TimeLogger. The setter member function allows it to inject the new logger. The client is fully decoupled from the logger. It simply supports the interfaces to inject loggers.
Here is the output of the program.
There are many examples of Dependency Injection using template parameters in the Standard Template Library. I only name here a few of the containers.
- The containers of the STL use a default allocator. This one can be replaced with a custom allocator.
- The ordered associative container use
std::lessas the sorting criteria. Of course, you can replace it with another sorting criterion.
- The unordered associative containers require a hash function and an equal function. Both are template parameters and can, therefore, be replaced.
Finally, let me write a few words about the three remaining creational Design Patterns.
The Three Remaining Creational Design Patterns
Abstract Factory lets you produce families of related objects without specifying their concrete classes. A typical example could be an IDE theme that consists of many related objects. For example, each IDE theme has different widgets, such as checkboxes, sliders, push buttons, and radio buttons. Typically, a concrete IDE theme has different factory methods for the various checkboxes, sliders, push buttons, and radio buttons .. . A client could change the IDE theme and, therefore, the widgets during the use of the IDE.
Builder construct complex objects step by step. Thanks to the builder pattern, you can produce different types and representations of an object using the same stepwise construction process. The builder extracts the object construction code out of its class and moves it to separate objects called builders. Not all steps of the construction process must be called, and a step can have more than one builder.
Prototype creates objects by cloning an existing object. The program
factoryMethodWindowSlicingFixed.cpp in my previous post “The Factory Method (Slicing and Ownership Semantics)” is a prototype. The Prototype Pattern is similar to the factory method, but emphasizes the created prototypes’ initialization. The factory method creates different objects by subclassing them.
My next posts about Design Patterns are dedicated to the structural pattern. I will start with the adaptor pattern, which can be implemented in two ways: multiple inheritance or delegation.
Thanks a lot to my Patreon Supporters: Matt Braun, Roman Postanciuc, Tobias Zindl, G Prvulovic, Reinhold Dröge, Abernitzke, Frank Grimm, Sakib, Broeserl, António Pina, Sergey Agafyin, Андрей Бурмистров, Jake, GS, Lawton Shoemake, Jozo Leko, John Breland, Venkat Nandam, Jose Francisco, Douglas Tinkham, Kuchlong Kuchlong, Robert Blanch, Truels Wissneth, Kris Kafka, Mario Luoni, Friedrich Huber, lennonli, Pramod Tikare Muralidhara, Peter Ware, Daniel Hufschläger, Alessandro Pezzato, Bob Perry, Satish Vangipuram, Andi Ireland, Richard Ohnemus, Michael Dunsky, Leo Goodstadt, John Wiederhirn, Yacob Cohen-Arazi, Florian Tischler, Robin Furness, Michael Young, Holger Detering, Bernd Mühlhaus, Matthieu Bolt, Stephen Kelley, Kyle Dean, Tusar Palauri, Dmitry Farberov, Juan Dent, George Liao, Daniel Ceperley, Jon T Hess, Stephen Totten, Wolfgang Fütterer, Matthias Grün, Phillip Diekmann, Ben Atakora, Ann Shatoff, Rob North, Bhavith C Achar, and Marco Parri Empoli.
Thanks, in particular, to Jon Hess, Lakshman, Christian Wittenhorst, Sherhy Pyton, Dendi Suhubdy, Sudhakar Belagurusamy, Richard Sargeant, Rusty Fleming, John Nebel, Mipko, Alicja Kaminska, Slavko Radman, and David Poole.
|My special thanks to Embarcadero|
|My special thanks to PVS-Studio|
|My special thanks to Tipi.build|
|My special thanks to Take Up Code|
I’m happy to give online seminars or face-to-face seminars worldwide. Please call me if you have any questions.
- Embedded Programmierung mit modernem C++ 12.12.2023 – 14.12.2023 (Präsenzschulung, Termingarantie)
Standard Seminars (English/German)
Here is a compilation of my standard seminars. These seminars are only meant to give you a first orientation.
- C++ – The Core Language
- C++ – The Standard Library
- C++ – Compact
- C++11 and C++14
- Concurrency with Modern C++
- Design Pattern and Architectural Pattern with C++
- Embedded Programming with Modern C++
- Generic Programming (Templates) with C++
- Clean Code with Modern C++
- Phone: +49 7472 917441
- Mobil:: +49 176 5506 5086
- Mail: schulung@ModernesCpp.de
- German Seminar Page: www.ModernesCpp.de
- Mentoring Page: www.ModernesCpp.org
Modernes C++ Mentoring,