Before 2003 and the inception of DDD, engineers and architects were thinking about how to organize their software and systems in a way that represented the problem space (domain) they were trying to model. As software became more and more complicated, it became apparent that the closer your system was to the domain, the easier it was to make changes. More importantly, it was easier for other stakeholders to converse with engineers as there was less of a disconnect between the real-world model of the problem space and the system model.
This was the issue that Eric Evans, a software engineer, was facing—the increased complexity of systems and failures in creating and maintaining them. This led him to write the book Domain-Driven Design: Tackling Complexity in the Heart of Software, Addison-Wesley Professional, in 2003—the first book on the subject of DDD.
“...(The) book Domain-Driven Design was an attempt to capture for people the successful practices that I had seen or used, some of which have been around for a long time and some of which are relatively new, and put together into a coherent set of practices with clear names so that maybe we can have broader success than we have in the past… a great deal of domain-driven design comes straight out of good old-fashioned object-oriented design patterns.” (Evans, in an interview with Software Engineering Radio, 2019, Episode 8: https://youtu.be/7yUONWp-CxM)
What does Evans mean when he refers to object-oriented design (OOD) principles? It used to be a given that everyone would write some object-oriented (OO) code as they began their journey into software development, but that is not necessarily the case anymore. If you are reading this book and Golang is your first programming language, it might be that you have never written traditional OO code.
OO programming (OOP) is a way to write programs that allows us to organize our code around objects rather than functions. We give these objects attributes and methods that define behavior.
OOP is particularly popular for large complex code bases as OOP is much easier to reason about. One of the most popular OOP languages is Java.
If we were building a human resources (HR) system, we might want to model an employee. If we were using Java, we might write this as follows:
public class Employee {
private String firstName;
private String lastName;
public Employee (String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return this.firstName;
}
public String getLastName() {
return this.lastName;
}
public String toString() {
return "Employee(" + this.firstName + "," + this.lastName + ")";
}
}
As you can see from this basic example, the code is readable, and we can easily model an employee in the system. When the business requires us to print a list of all employees or add the ability to store an employee’s location in their profile, you can hopefully see how our current Employee
class forms the basis to add such functionality.
Now that we have learned what OO code looks like, we can review some of the design patterns that are commonly used and that inspired DDD.
So, what are OOD patterns?
Design patterns were first described in 1977 in a book titled A Pattern Language: Towns, Buildings, Construction, by Christopher Alexander, Oxford University Press. This book has nothing to do with software engineering, yet it inspired one of the most influential books on OOP design, called Design Patterns, Elements of Reusable Object-Oriented Software, by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides, Addison-Wesley Professional. This book was released in 1995 but still features at the top of computer science students’ reading lists in 2022. You may have heard of this book by its colloquial name, the Gang of Four (or GoF), in reference to its four authors.
In the GoF book, 23 design patterns are outlined for what the authors believe lead to scalable, maintainable OO software. Going through each pattern is beyond the scope of this book (the GoF book comprises ~400 pages).
However, if you have read the GoF book, as you proceed to learn more about DDD, it is worth taking a pause and seeing whether you can see where Evans’s inspiration came from. The GoF patterns are split into the following sections, which are equally important when considering DDD:
- Creational patterns are patterns concerned with creating objects instead of creating objects directly. This gives more flexibility to the program in deciding which object type to create, given the current context.
- Structural patterns are concerned with how you compose objects within your program to achieve certain functionality.
- Behavioral patterns are concerned with how objects communicate.
Now that we have learned a little about what inspired DDD, let’s talk about the book that started it all.