Creational Patterns
Creational
Structural
Behavioral
- Chain of Responsibility (opens in a new tab)
- Command (opens in a new tab)
- Interpreter (opens in a new tab)
- Iterator (opens in a new tab)
- Mediator (opens in a new tab)
- Memento (opens in a new tab)
- Observer (opens in a new tab)
- State (opens in a new tab)
- Strategy (opens in a new tab)
- Template (opens in a new tab)
- Visitor (opens in a new tab)
Objective
- Creational design patterns.
Design Patterns
Design patterns are proven, reusable solutions to common problems that occur in software design. They represent best practices that experienced developers have refined over time, and they can be adapted to fit various situations. Each pattern provides a standard template for solving specific design challenges, which helps streamline the development process and improve code maintainability and scalability.
Design patterns offer several benefits:
- Promote reusability: By using design patterns, developers can apply tried-and-true approaches to solve problems more efficiently without reinventing the wheel.
- Enhance code maintainability: Well-structured solutions simplify future modifications and reduce the risk of bugs when making changes.
- Improve communication: Design patterns provide a common vocabulary for developers, making it easier to discuss and share ideas.
- Facilitate scalability: Patterns often enable systems to be designed with future growth and additional functionality in mind.
- Enforce best practices: Using patterns encourages developers to adhere to proven coding principles, which results in more robust and reliable software.
Design patterns are generally categorized into three main types:
- Creational patterns: Focus on the process of object creation.
- Structural patterns: Deal with object composition and the relationships between entities to create larger, more complex structures.
- Behavioral patterns: Concerned with the interaction and responsibility between objects.
By applying the appropriate design patterns, developers can create more maintainable, flexible, and efficient code that aligns with established best practices.
Code refactoring refers to the process of restructuring an existing codebase without changing its external behavior, while ensuring that the corresponding UML diagrams, such as class, sequence, or activity diagrams, are updated to reflect these changes. This practice helps improve the design, structure, and maintainability of the software.
Refactoring might involve:
- Reorganizing class structures: Modifying class hierarchies or relationships (e.g., extracting a superclass, merging classes) to make the design clearer and reduce duplication.
- Improving method cohesion: Splitting or merging methods, adjusting their interactions in sequence diagrams to enhance code readability and reduce complexity.
- Renaming elements: Updating class, attribute, or method names in both the code and UML diagrams to make them more meaningful.
- Encapsulation adjustments: Modifying access controls or moving methods between classes while updating diagrams to match.
- Simplifying interactions: Streamlining complex process flows represented in activity or sequence diagrams by refactoring logic.
Overall, the goal of code refactoring is to maintain consistent documentation and improve the system’s design quality without altering the end functionality.
“There are so many variations on the “there are only two hard problems in computer programming…” joke that I’m starting to suspect that programming isn’t actually very easy.” —Nat Pryce
Creational Patterns
- Singleton: Single instance control
- Factory: Object creation delegation
- Abstract Factory: Related object family creation
- Builder: Step-by-step object construction
- Prototype: Object cloning
Singleton
How do we ensure a class has only one instance throughout the application while providing global access to it? For example, an application configuration that should be loaded once and shared.
- Need to control access to shared resources (database connections, thread pools)
- Configuration settings that should be consistent across the application
- Want to prevent multiple instantiations of resource-heavy objects
Factory
How can we create objects without explicitly specifying their exact classes, allowing subclasses to alter the type of objects being created? For example, a document processing system that handles different file formats.
- Need to delegate object creation to subclasses
- Do not know ahead of time what types of objects need to be created
- Want to encapsulate object creation logic
Abstract Factory
How do we create families of related objects without specifying their concrete classes, ensuring the products are compatible? For example, cross-platform GUI components that must maintain consistent look and feel.
- Need to ensure created objects work together
- System must be configured with one of multiple families of products
- Want to enforce consistency across product families
Builder
How can we construct complex objects step by step, allowing different representations using the same construction process? For example, a document editor that can create documents in multiple formats or a meal ordering system that allows customization.
- Object needs to be created with numerous possible configurations
- Want to create different representations of the same complex object
- Need fine control over the construction process
Prototype
How can we create new objects by cloning an existing object (prototype) instead of creating new instances from scratch? For example, a document editor that can duplicate existing documents or creating game objects with different states but similar base attributes.
- Creating new objects is resource-intensive
- Want to avoid subclassing for object creation
- Need to create objects with varying configurations at runtime
Exercise 1
Design class diagrams that use at least three creational design patterns.
Explore the 10 SOLID + GRASP guide to learn more about the SOLID principles and GRASP patterns.
Structure
creational.vppfactory.patprototype.patsingleton.pat
Resources
- Visual Paradigm: Visual Paradigm tutorials (opens in a new tab), Using design pattern (opens in a new tab)
- Refactoring.Guru (opens in a new tab), SourceMaking (opens in a new tab), Patterns.dev (opens in a new tab)
- Gangs of Four (GoF) design patterns (opens in a new tab)
- GoF design patterns examples (opens in a new tab)
- Deceptive Patterns (opens in a new tab)
- Code refactoring using IntelliJ IDEA (opens in a new tab)
- Code refactoring (opens in a new tab), Principle of least astonishment (opens in a new tab), Law of Demeter (opens in a new tab), Separation of concerns (opens in a new tab), Aspect-oriented programming (opens in a new tab), POSA (opens in a new tab)