An Introduction to Creational Design Patterns
Different mechanisms to create objects without calling new() directly
Introduction
After a year-long diversion into Automated Testing, I’ve completed the series, and I’m returning to Design Patterns with a series on Creational Design Patterns.
If you’ve ever wrestled with unwieldy constructors or tangled initialization logic, Creational Design Patterns offer proven solutions. Creational Design Patterns help software engineers control object creation, ensuring flexibility, testability, and scalability. Whether you need a single shared instance, a family of related objects, or assembled objects configured from a blueprint, these patterns offer time-tested solutions to common problems of initialization and configuration.
This series will walk you through several core patterns—what they are, when to use them, and how they simplify your code.
The Gang of Four’s Creational Design Patterns
The Gang of Four (GoF) organized their catalog of Design Patterns into three major categories, with the first category being the Creational Design Patterns. The other two are Structural Design Patterns and Behavioral Design Patterns. Structural patterns focus upon the organization of objects, and behavioral patterns focus upon their behaviors. Quite frankly, I’ve often felt like the GoF’s assignment of design patterns between the structural and behavior categories was somewhat arbitrary, which is why I don’t tend to focus upon their categorization.
I introduced the Gang Of Four Creational Design Pattern Inventory as a section within the Factory Design Pattern, but I didn’t provide too much detail. I’ll provide more details in subsequent blogs in this series.
These are patterns that allow the caller to acquire an object without being coupled to the class type for the object returned. The caller will reference the objects as an abstraction, such as an interface, which aligns with the GOF’s first design principle: Program to an interface, not an implementation.
Programming to an interface decouples software components and encourages a more modular design. It allows different class types to satisfy the caller’s reference including Test Doubles which makes testing easier.
The Creational Design Patterns
The GoF cataloged five Creational Design Patterns. I include a few more. Here is my set, each of which will link to a blog dedicated to that pattern when written:
- Factory – Factory creates and returns an object without the caller having to know the object’s class type. I suspect it’s the most frequently used Creational Design Pattern. I consider it one of the Essential Design Patterns, which is why I featured it almost two years ago.
- Abstract Factory – Most Creational Design Patterns feature static methods defined in concrete classes known to the caller, even when the caller is an external Configurer from the primary business logic. With Abstract Factory the caller doesn’t know the Factory’s class type. The caller accesses the Factory as an interface. This allows a design to inject any Factory into the business logic. Abstract Factories have at least two primary features:
- An Abstract Factory is often a Factory of Factories. This ensures that cohesive objects of different types created by different Factories are consistent. For example, if the caller requires several objects, Abstract Factory helps ensure that those objects will be consistent within the same environment or scenario, such as production or testing.
- When business logic needs to create repeated instances of objects, the Abstract Factory pattern allows it to do so without coupling to specific factory implementations. Instead, a Configurer injects an Abstract Factory, from which the caller requests objects. By injecting different concrete factories—such as production or test variants—the Configurer controls which objects are created, while the caller remains decoupled from any specific implementation. This allows the caller to create as many objects as needed without direct dependencies on concrete factories.
- Builder – Most Creational Design Patterns create and return one instance of a class. Builder creates, assembles and returns a set of cohesive objects often organized as a data structure with a root object, such as a List or Tree. Builder is often used with Composable Design Patterns. Builder has two primary features:
- The creation and assembly of cohesive objects based upon a plan much like a blueprint. Builder allows us to construct objects based upon a text configuration rather than being hardcoded within the Configurer.
- The Builder pattern supports abstraction. Different concrete Builders can resolve the abstraction within the same design allowing them to create and assemble different concrete instances of the same structure using the Strategy Design Pattern. I’ll provide more details about this in the Builder blog (TBD).
- Singleton – Some objects should have exactly one instance, such as: Spoolers, File Systems, System Clock, Repositories, etc. Singleton ensures that only one object is created for a class type. Unfortunately, Singleton tends to be overused and have a lot of baggage. There are some pitfalls associated with it as well. Even the GoF made a few mistakes in the Singleton portion of their book. I’ll cover these later in the Singleton blog (TBD).
- Flyweight (Also Known As Multiton) – The GoF cataloged Flyweight as a Structural Design Pattern, but I feel it’s really a Creational Design Pattern. It creates multiple instances of Singletons, which sounds like a contradiction, but it’s not. Flyweight ensures that only one instance of an object will be created for a given set of attributes. If an object is requested with an attribute profile that matches a previously created object, then the previously created object will be returned. If the object has a new attribute profile, then a new object will be created and returned. Multiton is a play on words, as in Multiple Singleton.
- Prototype – All other Creational Design Patterns know the set of concrete class types they create, even if they encapsulate this information from the caller. Prototype is unique in that this pattern doesn’t know the concrete classes it creates. Prototype creates new objects by instructing another object to create a copy of itself. Prototypes are useful when we don’t want to update a Factory every time a new class type is added to the design, for example when adding new game-play elements to a game, such as weapons, spells, prizes, etc. The name is unfortunate. Prototype is not the same concept as prototyping code for a proof-of-concept exercise. I feel that Breeder or Cloner may have been a better name for the pattern, but no one asked me.
- Object Pool – This pattern is not in the GoF Design Pattern catalog. It’s similar to Flyweight but still different. With Flyweight, objects are created as needed and shared subsequently. With Object Pool, objects are created at start up and lent to the caller when requested. They are not shared with others. They must be released back to the pool by the caller. Rental cars, library books and bowling alley shoes are real world examples of Object Pools. Users acquire them, use them, and then return them.
- Dependency Injection – Dependency Injection is not in the GoF’s catalog, but it should have been. Technically, it’s not actually creating objects, but it’s such an integral concept with object creation, that I feel it should have honorary creational status. Dependency Injection removes object creation from the application altogether by creating the object externally in a Configurer and injecting it as a dependency into the application. I consider it one of the Essential Design Patterns, which is why I featured it almost two years ago.
What the GoF Missed
The GoF missed a few things, which I’ve addressed previously:
- They were concerned with encapsulation, but they didn’t observe it in their Creational Design Pattern nomenclature. Most Creational Design Patterns have different method names, such as
create()
,make()
,getInstance()
,construct()
, andclone()
. They convey the creation mechanism, which makes them less flexible. I prefer a method name,acquire()
, that conveys the client’s desires more than the creational mechanism. I’ll useacquire()
in my subsequent design pattern examples rather than the terms used by the GoF. - They were a little sloppy with memory management. They don’t address it, and some of their pattern examples, especially in C++, leak memory. Garbage collection languages, such as Java, don’t require as much memory management as C++, but there are some considerations, which I’ll present with specific patterns. I had already presented this in The Omission of Sin within the Proxy Design Pattern. This will not be the only time I use the Proxy Design Pattern with a Creational Design Pattern.
Creational Design Patterns Are Not Mutually Exclusive
Creational Design Patterns are not mutually exclusive. They can work together. For example, Builder could be used to create and assemble a Composite Tree. The Non-Terminal Nodes in this tree could be created using Factory Methods, and the Terminal Leaf Nodes could be created using Singletons or Flyweights.
Summary
Creational Design Patterns give us proven strategies for managing object creation, whether we need strict control, flexibility, or scalability. From ensuring a single instance with Singleton to constructing complex objects with Builder, each pattern addresses a unique design challenge. Mastering these patterns equips developers to write cleaner, more maintainable code — and to choose the right tool for the right job.
References
- Creational Design Patterns via Wikipedia
- Creational Design Patterns via SourceMaking
- Creational Design Patterns via RefactoringGuru
- Introduction to Creational Design Patterns via Baeldung
- Understanding Creational Design Patterns: Building Blocks of Object Creation blog by Srishti Prasad
- Google Search: creational design patterns