GoF Design Patterns: A Brief Overview
Overview
Coming from a non-CS background, I never learned about design patterns. Over the years, as a research software developer during my Ph.D. and postdoc, it became increasingly important for me to understand their significance. When writing a large codebases that is expected to evolve over time and intended for widespread use, choosing the right design pattern can significantly impact your code’s future (and mental sanity).
My first introduction to the subject was through the incredibly creative refactoring.guru website by Alexander Shvets. Subsequently, I took an online course in Design Patterns, which covered most of the original GoF patterns and more. I also frequently referred to the classic Gang of Four (GoF) book on the subject.
However, I found myself wanting a quick cheat sheet for these patterns, since I do not remember the details when I need it in my day-to-day. Hence, I’ve created this blog to summarize these patterns through a simplified UML class diagrams. Ie’s not meant to be comprehensive, as there are many websites dedicated to the subject. Instead, it’s a simple and visual reference for those who, like me, prefer to have a quick overview at hand.
What is a design pattern?
As Klaus Iglberger puts it, a design pattern has a name and carries an intent. Each design pattern aims at reducing dependencies within different components of your code and providing a certain level of abstraction.
Design patterns can be divided into three main categories: creational, structural, and behavioral. The creational design patterns are concerned with providing various mechanisms to create objects. The structural design patterns deal with how classes and objects can be composed to form larger structures. The behavioral design patterns focus on how objects communicate and collaborate with each other to achieve specific tasks.
Creational | Structural | Behavioral | ||
---|---|---|---|---|
Singleton | Adapter | Command | ||
Factory Method | Decorator | Strategy | ||
Abstract Factory | Proxy | Observer | ||
Builder | Composite | Mediator | ||
Prototype | Bridge | State | ||
Flyweight | Iterator | |||
Chain of Responsibility | ||||
Memento | ||||
Template Method | ||||
Visitor |
Below I provide a brief summary of each design pattern and a simplified UML diagram. My goal is to provide a brief summary of each of these patterns, along with an example for where it may be used in a typical research software. More patterns will be added soon.
Singleton
Ensures that a class has only one instance and provides a global point of access to that instance.
classDiagram
class Singleton {
- instance: Singleton
- Singleton()
+ getInstance(): Singleton
}
Factory Method
Defines an interface for creating an object, but allows subclasses to alter the type of objects that will be created.
classDiagram
direction LR
class Creator {
<<abstract>>
+ factoryMethod(): Product*
+ someOperation()
}
note for Creator "unique_ptr<Product> p = factoryMethod() \n p->doStuff()"
class ConcreteCreator {
+ factoryMethod(): Product
}
note for ConcreteCreator "return make_unique<ConcreteProduct>()"
class Product {
<<interface>>
+ doStuff()
}
class ConcreteProduct {
+ doStuff()
}
Creator <|-- ConcreteCreator
ConcreteCreator ..> ConcreteProduct : creates
Product <|.. ConcreteProduct
Creator ..> Product : uses
Further Exploration
- Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides (The Gang of Four)
- Design Patterns, a Coursera course by Kenny Wong from University of Alberta
- refactoring.guru by Alexander Shvets
- Conceptual codes in C++ by Alexander Shvets
- Modern C++ Design: Generic Programming and Design Patterns Applied by Andrei Alexandrescu
Enjoy Reading This Article?
Here are some more articles you might like to read next: