Recently I joined a new project, and within reason, and excluding some legacy systems we have to talk to, we have the “luxury” of an almost greenfield project. Probably as greenfield as you realistically get anyway.
I was brought in partially as a good old fashioned coder (the project needed another person cutting code) and partly as guys in the team knew my blog and general approach to software development and wanted to inject some of those ideas into the team. I’m not sure exactly what they were expecting, and I’m not sure if they got what they were expecting, but suffice to say the first two weeks has been turbulent and frenzied.
I’m certainly not known for my subtlety, nor for my coding skills which are by no means the best you can buy in. What I feel is my key strength is my ability to look at the wider picture than sometimes teams have the luxury to do, and to push some of my enthusiasm and energy into a project. I’m sure I’ll blog in the near future about the actual impact my presence has had on the team and the project, but this blog is primarily about why we are not going to be doing DDD.
But Casey Does Domain-Driven Design
One of the factors that made the client hire me was my knowledge around DDD, or at least my projection of that knowledge on the web. It was certainly something they felt could have helped some of their past and ongoing projects, and something they thought would be a real help to them. I don’t think anyone suspected I would come in and say “Hey guys, lets all do full on DDD”, so luckily for them I didn’t, what may have surprised them is that I did pretty much the opposite. In fact my early assessment was this project really didn’t have any need for most of the stuff in DDD – fundamentally it, like the other projects in progress by the same team, was a CRUD application at heart. Data out of the DB, a bit of manipulation, some input by users and services, and dump the data back to the DB.
Many out there disagree with my general statement that CRUD applications don’t make good candidates for DDD – but not only do I stand by that statement, but two of the other client’s projects nearing completion showed some of the real pitfalls of DDD. While previous projects had attempted to use parts of DDD to help simplify their applications, it had not all gone according to plan.
What Goes Wrong With DDD Over CRUD – The DB Domain Model
The first most obvious weakness of the systems that existed was the Domain Model. It had started with all the best intentions – there was a legacy database that acted as the primary store for the business, and many different systems used and updated this database. So NHibernate was chosen as a way to create a Domain Model over the database, to abstract the system away from the DB and to treat it as a legacy system.
Unfortunately one of the primary requisites of DDD is direct involvement and commitment from the business to the project and in this case that wasn’t part of the project. The team had to come up with their own Domain Model – and in doing so had fallen into the classic pitfall of creating a “domain model” that mirrored the legacy database. Now not only was there a legacy database, but essentially there was a legacy domain model too. A large amount of work was put into getting this NHibernate model right, and in hindsight it has probably consumed disproportionate resources to get this model overlaying the DB.
In addition, although at present it simplifies many operations against the DB, it does not abstract the code base from the database, it just acts as a heavyweight data access layer. Worse still, many of the “hacks” that had to be made to get NHibernate to work with the (frankly terrible) underlying database structure, had actually made the system very fragile, and fairly rigid.
Lesson to be learned: Do not drive your domain model from the database, drive it from the Domain Experts, user stories and use cases. Without significant commitment from your business to provide you with those experts, you are at risk of creating a significant amount of code, with no quantifiable benefit.
What Goes Wrong With DDD – Where is The Ubiquitous Language?
A somewhat related problem that is now obvious, again in hindsight, is that there was no clear attempt made to extract any kind of Ubiquitous Language out of the (non-existent) domain experts, nor from the business analysts. The language between the teams has fallen into the classic pitfall of a language confused across development teams, technical support teams, legacy systems, and business terminology that was not clearly defined nor understood.
Lesson to be learned: Get your language sorted out early on. Insist upon a basic glossary of terms at the very minimum, regardless of whether you do DDD or not. This will save countless hours of mistakes and confusion, and will get new developers and business people up to speed on the project in record time.
What Goes Wrong With DDD – Services Services Services!
I sat down early on with numerous team members and the architect who was in the unenviable position of making all this stuff work, and ensuring all the new stuff learned from previous mistakes and moved forward.
One of the things that became apparent to me was that while discussing architectures, the term “Services” was in frequent use, more than frequent to be honest, it permeated through everything. It was a term that business analysts and project managers were comfortable with, and perhaps that was the reason that “Services” was the terminology for decoupling things. From that it soon became obvious that Services of all kinds had become intrinsic to the current codebase, from Web Services, to Application Services, to Domain Services, and on and on.
Now, there is nothing wrong with “Services” per se, but interestingly when I suggested a new architecture for the new project, and discussed this with various people, I managed to explain the entire new architecture with almost no use of the word “Services”.
When I pointed this out, it soon became clear we could discuss a decoupled system, with little direct reference to “Services”, as fundamentally Services are an implementation detail, and have little important to the overall architecture of a system. Now instead of talking about Service being called, we can discuss messages being moved around the system, without any need to worry about what consumes them, or how they are delivered. The final architecture includes services for sure, but they are the implementation of a much more abstract concept.
Lesson learned: Technical language can become the norm, and then it tends to be the solution to every problem. Step back from things once in a while, and see if the terminology you are using is driving your architecture and design. Try to avoid using implementation terminology in relation to things like architecture, or it will drive the design.
So Where Are We Now?
The one really big thing that has happened over the past two weeks is that the introduction of some new blood to the team, along with some new ideas, has really revitalised the team. Everyone has new found energy. We also have a broad consensus of what didn’t go right on the last two projects, and the things that went well – we now have a strong idea of how to build on the strengths of the existing systems, and where we need to compensate for the things that didn’t turn out as planned.
Luckily the teams involved are all really eager to learn, and really keen to make each and every system better – and that alone will make a huge impact to how successful this project will be.
Well, this post has turned into a bit of an EPIC … and is far too long to continue without boring everyone to death … so I will post the concluding part soon. And with luck I may explain my opening statement … “We Are NOT Doing DDD”.
04-08-2009 9:34 PM