The other day, I saw something that really encompasses one of the biggest hurdles for younger developers to get through. That hurdle is terminology. These days, there is all sorts of "___ driven development". In our team, we even joke about "assumption driven development".
Naming things is one of the hardest things to deal with in programming. It gets worse when we are doing something that is uncomfortable. Make it worse, before we ever started programming there are tons of people who have already named things (and naming things was hard for them too).
And see, this is where we as a community come in and can help people understand things a lot easier. Of course it doesn't hurt if we don't muck up some serious patterns and terminology even more (no I'm not talking about Facades, the argument over that hurt the community more).
All The Driven Development
One of the big things that bothered me the other day was hearing someone say "you thought TDD was hard, wait until you change over to using DDD". Maybe it was out of context, but I think that at heart, a lot of young developers (especially those that are freelancing or the most senior on a small young team) get confused. It used to be information on software patterns was a bit more limited: you hear something from a close coworker, that one message board you subscribe to, a professor, a senior dev, etc then you use it. Now, we face massively social communities where everyone spouts their ideas on Twitter, G+, SO, and more. A developer that would have been slowly introduced to design patterns, Extreme Programming/Agile Development, and best practices are instead bombarded with everything at once.
So I hope to clarify some confusion of thinking that TDD (Test Driven Development) and DDD (Domain Driven Development) are somehow in competition or mutually exclusive. They aren't in fact! So I'll dig in to what I've taken out of the two methods and where they fit together.
What Is TDD
TDD is the process of writing tests based on a particular desired pieced of functionality, letting them fail. Then you write the least amount of code possible to make the test pass, then write another test. Cycle this over and over until you have finished a feature and then go back and refactor. It's a bit simplified, I know, but this is the heart of TDD. Don't get stuck in the mud about it! Don't worry about techniques, code structure, etc.
Don't let people fool you!
TDD is just the process of testing code before writing it!
What Is DDD
DDD takes a bit more explaining. You see, a Domain is a set of functionality that you are attempting to mimic that lies outside of your application. Maybe this is a physical event like an election, maybe it's something a bit more arbitrary such as a source code project initializer. You will want to assign a Domain Expert, this could be your project manager, yourself when you put on your spec writing hat for a new side project (that is really dangerous though), but most likely, your Domain Expert will be your client. The point is, to create something, you must first understand what it is you are trying to create! DDD describes the process of consulting and deciding on explicit definitions of each piece of the domain that you are trying to mimic. And you make sure that these definitions are written before ever writing code. Then these definitions and naming structures from your domain study are used to create a more informed code base. Then when you pick your head up for the next change, error, fix, whatever: you consult with the Domain Expert and turn programming talk back into the Domain terminology.
Don't let people fool you!
DDD is the process of being informed about the Domain before each cycle of touching code!
Mixing the Two Together
Alright, so now lets see WILL IT BLEND!? That is the question. DDD lives mostly in how you research before coding, how you name things, and how you interact with the client. On the other hand, TDD is the process of actually writing your code. So, as you can see, there is no conflict of interest between the two strategies and they fit together quite well.
Ok, I Lied... A Bit...
If you read Eric Evan's book on Domain Driven Development and Martin Fowler's Blog, you will see that their process of Domain Driven Development goes beyond just getting an informed view of the domain and describing it with "ubiquitous language". They include code coverage, continuous integration, a testing strategy, and code organization as part of the DDD life cycle. While these things do happen between getting domain information from a client before coding and then translating things back to the domain expert, I'm not so sure that these are really part of DDD. Let me explain.
If as good programmers (and good DDD programmers at that), we decide to break things down into their unique single role parts we'd see a few things when examining the formation of the DDD mindset. First, is that it borrows heavily from Extreme Programming. EP was a multi pronged approach to developing software in a more iterative and maintainable fashion. It included planning phases, writing tests, using continuous integration, and more. EP claimed that code was the most important thing in a software project, and developers should be prepared to code efficiently.
Evan's came in and took a lot from the toolbelt in front of him and created his own method to attacking software problems and he put understanding the domain first. This meant that while code was still really important, the best code in the world is only as good as the understanding of the problem you are trying to solve. At the end of the day, what makes Evan's process unique was the communication with a Domain Expert. It's this communication that I would argue IS DDD. Everything else was slight modifications on existing techniques.
A Word On Code Structure
I made a point that TDD as a philosophy doesn't care how you structure your code. There are those that would probably think that this transfers to DDD as well. Unfortunately it's a bit stranger than that. While the simplified view of DDD makes me want to say that code structure isn't part of DDD, I can't really tell you that. With a deep understanding of the domain and wanting to mimic the domain within the code base, your code structure will and should be influenced. Also on the other side of things, it makes the translation of software output to the domain expert much easier for you: if you are stuck remembering how this SuperDuperSoftwarePatternThing relates back to your domain, you aren't doing yourself any favors. Stick with efficiency and mimic the language you set up when talking with the client. If things are hard to structure, that's a sign that you may not understand the specifications for the different actors in the domain.
A Word On BDD
BDD is an implementation of TDD which brings in some aspects of DDD. BDD focuses on how to name tests and instructs that tests should start from outside interaction in. For instance if you want to go to a page and see some blog posts you'd write the test for the route, say "hey I want to see some posts", then you'll say "I need to get some posts from somewhere", then keep going until collide with unit tests at the low level.
BDD also goes to the effort of giving a more conversational way of writing tests. Since many tests start from the outside of a system and work their way in, BDD lends itself well to testing a pass or fail condition for a user story or feature. This means that you describe what actors are setting up a feature to be tested and then what result is to be expected. If you caught that, you may see that BDD lends itself as a TDD strategy for teams that have a solid domain definition from DDD. BDD is also often heralded because BDD testing tools can be arguably more human readable to non-developers such as Domain Experts.
So, did this help you? Did I get it wrong? Did I not go far enough?