From "Design Patterns"
🎧 Listen to Summary
Free 10-min PreviewSingleton Pattern
Key Insight
The Singleton pattern ensures that a class has only one instance and provides a global point of access to it. This is critical for classes where exactly one instance must exist throughout a system, such as a printer spooler, file system, or window manager, or an A/D converter in a digital filter. While a global variable can make an object accessible, it fails to prevent the creation of multiple instances. The Singleton pattern addresses this by making the class itself responsible for managing its unique instance, preventing further instantiations, and offering a controlled, well-known access point.
This pattern is applicable when there must be precisely one instance of a class that is globally accessible to clients, or when that sole instance needs to be extensible by subclassing while clients continue to use the extended instance without code modification. The 'Singleton' class defines an 'Instance' operation, typically a class or static method, which clients use exclusively to access its unique instance. The benefits include controlled access to the sole instance, as the class encapsulates and strictly manages its access, and a reduced global name space compared to using global variables. It also permits the refinement of operations and representation through subclassing, allowing run-time configuration with an extended instance, and offers greater flexibility than static class operations which cannot be overridden polymorphically.
Implementing a Singleton involves hiding the instance creation behind the class's 'Instance' operation, ensuring lazy initialization where the unique instance is created only upon its first access. In C++, this often means a 'protected' constructor to prevent direct instantiation, a static member variable to hold the instance, and a static 'Instance' method to return it, meticulously avoiding pitfalls associated with global static objects like uncertain initialization order. Subclassing a Singleton requires careful management of which subclass instance is installed; this can be achieved by determining the subclass within the 'Instance' operation (e.g., using environment variables), by fixing the choice at link-time, or more flexibly, by employing a registry of singletons where classes register their instances by name. For example, a 'MazeFactory' can be implemented as a Singleton, making its unique instance globally available to all parts of the maze-building code, and can be configured to instantiate specific 'MazeFactory' subclasses based on run-time conditions.
📚 Continue Your Learning Journey — No Payment Required
Access the complete Design Patterns summary with audio narration, key takeaways, and actionable insights from Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides.