In software engineering, there are numerous design patterns, but they are generally classified into three main categories based on the Gang of Four (GoF) classification. The GoF book, Design Patterns: Elements of Reusable Object-Oriented Software, introduced 23 classic design patterns, which are widely referenced in software development. In this post, I’ll walk through these categories, explain what each pattern is, when to use it, and their pros and cons. I’ll also relate each pattern to real-life examples so that it’s easy to understand, even for those new to the field.
1. Creational Patterns
Creational patterns focus on how objects are created, aiming to provide flexibility while constructing objects.
a) Factory Method
- What is it? A pattern that allows creating objects without specifying the exact class in advance.
- When to use: When the type of object is determined at runtime, but the exact type is unknown during development.
- Example: An app that can create different types of documents (PDF, Word, etc.) depending on the user's choice.
Pros: Flexible and reusable; no need to change client code when adding new types.
Cons: Can result in many subclasses, increasing complexity.
b) Abstract Factory
- What is it? Provides an interface for creating families of related or dependent objects without specifying their concrete classes.
- When to use: When you need to create groups of related objects, such as a UI that should be rendered differently for Mac, Windows, and Linux.
- Example: A furniture shop where you can buy modern or vintage furniture, but each style requires matching chairs, tables, and sofas.
Pros: Ensures products work together; easy to swap families.
Cons: Adding new families can be difficult.
c) Builder
- What is it? A pattern that allows you to construct complex objects step by step.
- When to use: When an object requires many parts to be created, and the creation process is complex.
- Example: Think of ordering a customized burger where you choose the type of bread, meat, and toppings step by step.
Pros: Clear separation between construction and representation.
Cons: More complex than simply using a constructor.
d) Prototype
- What is it? A pattern that creates new objects by copying an existing object (prototype).
- When to use: When the cost of creating a new object is expensive or complex.
- Example: Duplicating a well-prepared cookie dough recipe instead of creating the dough from scratch every time.
Pros: Speeds up object creation.
Cons: Cloning complex objects with lots of references can be tricky.
e) Singleton
- What is it? Ensures that a class has only one instance and provides global access to it.
- When to use: When a single instance of a class is required throughout the application (e.g., database connections).
- Example: A country only has one national treasury, and every department accesses that same treasury.
Pros: Controls resource access; avoids unnecessary instance duplication.
Cons: Can introduce bottlenecks and hidden dependencies.
2. Structural Patterns
Structural patterns focus on the composition of objects and classes to form larger structures.
a) Adapter
- What is it? Converts the interface of a class into another interface the client expects.
- When to use: When a system needs to work with an existing class that has a different interface.
- Example: A power adapter that allows a US plug to work with a European socket.
Pros: Promotes reusability of existing code.
Cons: Adds complexity with additional layers.
b) Bridge
- What is it? Separates an object’s abstraction from its implementation so that both can be changed independently.
- When to use: When you want to vary not only how something is implemented but also how it is represented.
- Example: Think of remote controls that can be used with different TVs or home appliances.
Pros: Reduces coupling between abstraction and implementation.
Cons: Increases complexity with multiple layers.
c) Composite
- What is it? A pattern that allows treating individual objects and compositions of objects uniformly.
- When to use: When you want to treat a group of objects in the same way as a single object.
- Example: A file system where both files and folders (which contain files) are treated the same way.
Pros: Simplifies code for dealing with object hierarchies.
Cons: Can make the system overly general.
d) Decorator
- What is it? Adds behavior to individual objects dynamically, without affecting other objects.
- When to use: When you want to add responsibilities to an object without subclassing.
- Example: A coffee order where you can add extra ingredients like milk or sugar on top of the base coffee.
Pros: Flexible in extending behavior.
Cons: Can lead to too many small classes and complexity.
e) Facade
- What is it? A simplified interface to a complex subsystem.
- When to use: When you want to hide the complexity of a system and provide a cleaner interface.
- Example: A universal TV remote that simplifies controlling multiple devices (TV, sound system, streaming).
Pros: Simplifies client code.
Cons: Can hide necessary details, making the system harder to modify later.
f) Flyweight
- What is it? Reduces memory usage by sharing as much data as possible with similar objects.
- When to use: When many objects share some common data.
- Example: A game where all trees in a forest share the same texture, but each has different positions.
Pros: Reduces memory consumption.
Cons: Increases complexity by managing shared data.
g) Proxy
- What is it? Provides a surrogate or placeholder for another object to control access to it.
- When to use: When direct access to an object is expensive or not possible.
- Example: A virtual proxy for loading a large image on a website, where the proxy first shows a placeholder until the image is fully loaded.
Pros: Controls access and reduces resource usage.
Cons: Adds an extra layer of abstraction.
3. Behavioral Patterns
Behavioral patterns focus on how objects interact and communicate with each other.
a) Chain of Responsibility
- What is it? Passes a request along a chain of handlers until one of them handles it.
- When to use: When more than one object can handle a request, but you want only one to process it.
- Example: Think of a customer support system where queries pass from basic support to technical teams depending on complexity.
Pros: Decouples the sender and receiver of a request.
Cons: Can lead to unhandled requests if no handler processes them.
b) Command
- What is it? Encapsulates a request as an object, allowing it to be stored, logged, or undone.
- When to use: When you want to parameterize operations, queue requests, or support undo/redo.
- Example: A smart home system where commands can be sent to turn lights on/off.
Pros: Easy to extend with new commands.
Cons: Can introduce too many command classes.
c) Interpreter
- What is it? Defines a grammar for a language and interprets sentences in that language.
- When to use: When you need to evaluate sentences in a specific language.
- Example: A calculator that interprets mathematical expressions like "5 + 2".
Pros: Easy to add new language rules.
Cons: Not suitable for complex grammars.
d) Iterator
- What is it? Provides a way to access elements of a collection sequentially without exposing the underlying structure.
- When to use: When you need to traverse a collection (like a list or a map) without knowing its internal details.
- Example: A playlist app where you iterate through songs without knowing how the list is stored.
Pros: Simplifies traversing collections.
Cons: Can hide the collection's complexity, making modifications harder.
e) Mediator
- What is it? Reduces direct communication between objects by introducing a mediator object that handles the interaction.
- When to use: When many objects interact, but you want to avoid complex interdependencies.
- Example: Think of an air traffic control system where all planes communicate via the control tower rather than directly with each other.
Pros: Simplifies object interaction.
Cons: Can centralize too much logic in the mediator.
f) Memento
- What is it? Captures an object’s state to restore it later.
- When to use: When you need to implement undo or rollback functionality.
- Example: An art program where you can undo edits to an image.
Pros: Makes it easy to revert to previous states.
Cons: Can use a lot of memory for complex objects.
g) Observer
- What is it? A way for objects to notify others of changes.
- When to use: When one object needs to update many other objects when its state changes.
- Example: Social media notifications that alert you when someone likes your post.
Pros: Decouples subject from observers.
Cons: If not managed well, can lead to performance issues with many observers.
h) State
- What is it? Allows an object to change its behavior when its internal state changes.
- **When to use
:** When an object can behave differently depending on its current state.
- Example: A vending machine that behaves differently depending on whether it’s stocked or out of stock.
Pros: Simplifies code by avoiding complex conditionals.
Cons: Can introduce additional classes for each state.
i) Strategy
- What is it? Defines a family of algorithms and allows switching between them.
- When to use: When you want to select an algorithm at runtime based on the context.
- Example: A tax calculator that applies different tax strategies depending on the country.
Pros: Promotes flexibility by decoupling the algorithm from the client.
Cons: Requires clients to know about different strategies.
j) Template Method
- What is it? Defines the skeleton of an algorithm, allowing subclasses to implement specific steps.
- When to use: When a method’s general structure is the same, but certain steps need customization.
- Example: A baking recipe where the basic steps (mix, bake, cool) are fixed, but the ingredients can vary.
Pros: Avoids code duplication by reusing common logic.
Cons: Limits flexibility by enforcing a predefined structure.
k) Visitor
- What is it? A pattern that lets you define new operations on an object structure without changing the classes of the objects.
- When to use: When you need to perform operations on an object structure but don't want to change the structure itself.
- Example: A tax app where tax rules are applied to different types of income (salary, rental, etc.) without modifying the income types.
Pros: Makes it easy to add new operations.
Cons: Can make code difficult to understand due to the separation of concerns.
While I love to write to educate others, I also to collaborate and my door is still open. Do reach out to me if you need my services:
Gmail: Adeshinaibrahim10@gmail.com
Portfolio: https://usool-data-science.github.io/portfolio
Top comments (0)