DDD itself is such a huge field that I feel it is hard to get something to work without sharing experiences. One of my tasks here at Sclable was to design and implement a DVC (domain view controller) Framework in PHP. In this blog post I’d like to give you some insights on my findings over the last year. I just recently put together some slides for a talk at the PHP Meetup in Munich. The event was overbooked, so this post is also for everyone who wanted to join and couldn’t make it.
Before going into details I have to make a restriction regarding the type of software projects I am talking about. Since at Sclable we are specialized in business applications, I am not talking about production plant automatisation for example (just another field I have experience in). What I mean by business applications is quite the same what Martin Fowler means by his term “Enterprise Applications”.
Clear Your Concepts Before You Start
Mahmud Hasan, a software engineer from Bangladesh has got some slides for a good introduction online as I feel. So for the “What the heck is DDD?” part of my talk I am referencing his presentation – though I’ve never had the chance to see or hear it. I won’t go much into detail about DDD. Rather I’d like to show you, what is possible with PHP once you have a domain model. (If you want to skip the conceptual part, go right to the end of this post…)
The Traditional Way
DDD advocates are not saying that NOT doing DDD is wrong. This would be plain stupid as it really depends on the nature of your software project. There is nothing wrong with reading specifications, defining functionalities and features, estimating ressources, breaking down and distributing tasks, designing a database schema and finally: start coding.
Such software projects can be as successful as any DDD based software project. No matter if you are using an agile or classical development method. But after the first production release you might realize that your team is not doing so well in maintaining or extending the software.
That is where DDD comes into play. Instead of a bottom-up fashion DDD supports lean and agile software development in a way that you can iterate more often, still delivering results with every iteration. That is especially helpful if there is not a single person within the software project team that can fully grasp the business domain. DDD is a way of thinking that allows you to “tackle complexity in the heart of software” as Evans puts it.
Without going into the deepest spheres of DDD I suggest anyone who is keen to actually code something before going through all the literature, to start off with understanding those terms, which are the most important in my opinion: Domain, Model and Entity. These will quickly lead to your “Domain Model” which basically consists of entities.
At the start, your domain language (or ubiquitous language), should resemble a set of entities along with a naming and descriptions that everyone from business people to technicians understands and agrees with. Avoid technical terminology. Try to be meaningful when setting up your entities. Do not underestimate the distinctiveness of your domain language. The closer you are to reality the greater the use will be that your domain model will be able to provide.
Ubiquitous Language, Doubly Linked Lists and Magic Methods
Finally I am reaching the “Implementing” part. Imagine your domain as a knowledge base rather than a data base. For my DDD framework I designed a few base classes: domain, module, entity, attribute. And all my base classes are organized within my DomainManager. My domain objects are linked by a “double chained list” or “doubly linked list”. Some default methods help for example to get all modules of a domain or all entities of a module. And when I want to use my domain objects, magic methods come into play.
Let’s look at a simple question that should be answered by a business application. Usually the question itself originates from a human need. Of course there should be some sort of storage, e.g. an RDBMS where the data for the answer is stored. As a software developer it is yours to align those two.
Human (an Accounting Manager):
„I need a detailed list of all items of the invoice with the number A2014223“
In the Database:
SELECT * FROM phpMoney__accounting.invoice_items WHERE invoice_id = (SELECT id from phpMoney__accounting.invoices WHERE number = ‘A2014223‘);
$list = DM::domains()->phpMoney()->accounting()->invoice_items()->where([…])->execute();
The Method Magic
For the above example I am using PHP’s magic methods __call(), __get() and __set(). I am currently preparing a functional example along with source code for you to fork. So my next blog post will be exactly about that: How to use magic methods, what you should be aware of when utilizing them and, apart from the conceptual and DDD related reasons, what technical considerations led to my approach.
The Idea of using DDD and utilizing PHP’s features like magic mehtods is to allow your developers to write code in “domain language”. Imagine an IDE fully aware of your domain model, thus doing code completion for you! Imagine you one of them changes the domain model on a feature branch, and other developers get alerts upon checkout, which parts of their code need refactoring!