Domain-driven design and PHP - Part 1: Introduction

Aug 09, 2009

This is the first post in a series on the subject of Domain-Driven Design and its use in PHP development.

If you’re reading this, I’ll assume that you already have a reasonable knowledge of PHP, although it’s not essential. Before going any further, I’ll explain the basic notion of what DDD is, and why you might want to care about it. Fortunately, I’ve already written a basic introduction to DDD in a response to a question on Stack Overflow, which I’ll reproduce here:

Firstly, if you don’t know that you need it then it’s possible that you don’t need it. If you don’t recognize the problems that DDD solves then maybe you don’t have those problems. Even DDD advocates will frequently point out that DDD is only intended for large (>6 month) projects.

Assuming that you’re still reading at this point, my take on DDD is this:

DDD is about trying to make your software a model of a real-world system or process. In using DDD, you are meant to work closely with a domain expert who can explain how the real-world system works. For example, if you’re developing a system that handles the placing of bets on horse races, your domain expert might be an experienced bookmaker.

Between yourself and the domain expert, you build a ubiquitous language, which is basically a conceptual description of the system. The idea is that you should be able to write down what the system does in a way that the domain expert can read it and verify that it is correct. In our betting example, the ubiquitous language would include the definition of words such as ‘race’, 'bet’, 'odds’ and so on.

The concepts described by the UL will form the basis of your object-oriented design. DDD provides some clear guidance on how your objects should interact, and helps you divide your objects into the following categories:

  • Value objects, which represent a value that might have sub-parts (for example, a date may have a day, month and year)
  • Entities, which are objects with identity. For example, each Customer object has its own identity, so we know that two customers with the same name are not the same customer
  • Aggregate roots are objects that own other objects. This is a complex concept and works on the basis that there are some objects that don’t make sense unless they have an owner. For example, an 'Order Line’ object doesn’t make sense without an 'Order’ to belong to, so we say that the Order is the aggregate root, and Order Line objects can only be manipulated via methods in the Order object

DDD also recommends several patterns:

  • Repository, a pattern for persistence (saving and loading your data, typically to/from a database)
  • Factory, a pattern for object creation
  • Service, a pattern for creating objects that manipulate your main domain objects without being a part of the domain themselves

Now, at this point I have to say that if you haven’t heard of any of these things before, you shouldn’t be trying to use DDD on any project that you have a deadline for. Before attempting DDD, you should be familiar with design patterns and enterprise design patterns. Knowing these makes DDD a lot easier to grasp. And, as mentioned above, there is a free introduction to DDD available from InfoQ (where you can also find talks about DDD).

So, DDD is an approach to system design that is useful on large projects that involve complex systems. DDD is great when you’re dealing with a well-defined system and you have experts on hand to explain how that system needs to function. If you’re writing software to automate factory processes, you need access to a shop floor manager who can tell you everything about how those processes operate. Not every project is like this. Sometimes you’re creating software that’s quite open-ended, where you’re not sure exactly what the outcome is going to be at the end of the project. Whilst some DDD principles can help here, not all of it will be applicable. For small projects, the overhead of DDD is simply unnecessary - pragmatism may dictate that it’s better to just get the job done rather than worry about the best possible design method.

As of now, DDD has gained a widespread following amongst 'enterprise’ developers using .NET or Java, but isn’t widely known in the PHP world. This is because the large-scale projects for which DDD is best suited are still relatively rare in PHP - they exist, but they exist alongside many more smaller projects that do not require DDD.

Recently, there have been some huge developments in the PHP world, which mean that large-scale projects are much more achievable than in the past, and PHP has found a new role in large-scale web projects that might previously have been done using Java or .NET. In his post on the subject, Cal Evans talks about how PHP is now being used by web innovators such as Digg and Facebook, as well as blue-chip corporates. PHP 5.3 has added some powerful new language features and has addressed issues of performance, stability and reliability. The Zend Framework provides implementations of many key design patterns which serve as the building blocks of both code and the design of code.

In summary, I think that the PHP community has a great opportunity to learn from other communities who have been solving enterprise problems for years. Concepts such as Domain-Driven Design can help us to make better software. In this series of posts, I’ll cover DDD from a PHP perspective, explaining how it can be applied from the perspectives of design and coding.

The next post in this series will cover the groundwork, introducing the basic design patterns that are present in all DDD projects.