A certain few of the GOF design patterns show up a lot, in most cases programmers use them without consciously deciding to “use a design pattern”.
- singleton: most often this is nothing more than a global variable in OOP clothing - a static method to get. People will always need global variables.
- iterator pattern: used in almost every standard library with containers, and that’s not counting “incremented pointers”, even though that often can provide a similar interface.
- strategy pattern: often using some form of language-provided dynamic dispatch (virtual, or functor). Picking behavior at run time is a very powerful tool, even if at some level it just boils down to branching, switching, or looking up.
- Factory pattern: essentially just the strategy pattern applied to object creation, usually achieved in the same ways.
- observer pattern: nearly every game engine or other system with “tasks” will have something similar. Some forms of reference counting and concurrency even imply its use.
- visitor pattern: the popularity of observer and strategy pattern often results in many uses of the visitor pattern: “I have a list of objects I need to inform of an event, but the objects are generic. I’ll have them all share some common interface so I can iterate over them and call the right method for each.”
Creational patterns
Abstract factory
Factory method
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
Motivation
The Factory Method design pattern solves problems like:
- How can an object be created so that subclasses can redefine which class to instantiate?
- How can a class defer instantiation to subclasses?
The Factory Method design pattern describes how to solve such problems:
- Define a separate operation (factory method) for creating an object.
- Create an object by calling a factory method.
Implementations
|
|
|
|
Singleton
The pattern is useful when exactly one object is needed to coordinate actions across a system.
The singleton pattern allows objects to:
- Ensure they only have one instance
- Provide easy access to that instance
- Control their instantiation (for example, hiding the constructors of a class)
Common uses
Singletons are often preferred to global variables because they do not pollute the global namespace (or their containing namespace). Additionally, they permit lazy allocation and initialization, whereas global variables in many languages will always consume resources.
Logging is a common real-world use case for singletons, because all objects that wish to log messages require a uniform point of access and conceptually write to a single source.
Implementations
Implementations of the singleton pattern ensure that only one instance of the singleton class ever exists and typically provide global access to that instance.
Typically, this is accomplished by:
- Declaring all constructors of the class to be private, which prevents it from being instantiated by other objects
- Providing a static method that returns a reference to the instance
The instance is usually stored as a private static variable; the instance is created when the variable is initialized, at some point before when the static method is first called.
|
|