Today I had the opportunity to
practice some more test driven development with a resident expert in the field,
Scott Bellware.
Scott is a really excited and engaging guy to be around. He's really taken
on Domain Driven Design, he believes in it, and he can teach it like you would
teach someone to tie their shoes. It's simply second nature for
him. I consider myself a relatively accomplish IT professional. I
know my way around all flavors of C code, object oriented design, and
implementation. Typically I come from the school of thought that you plan
what you are going to build before building it. Write it all down, figure
out the hard problems, chop them into smaller, more manageable ones. Show
your solution to someone else, let them tear it up, and before you start
writing any code you have a pretty good idea of how version 1.0 of what you are
creating will look like. Now this is an abbreviated summary of
development, but that being said you can push it into waterfall with
milestones, or agile with a backlog and sprints.
Milestones and sprints are both organizational process. They have very
little to do with actual development. Domain Driven Design is the bible for this style
of development, and we got to experience a little piece of it implementing just
a few straightforward rules in part of a hypothetical system. I have not
read the book, although it is now on the top of my list.
The paradigm as experienced in an afternoon is code to the test, and isolate
your functionality into 'domains.' Coding to the test is essentially
writing your tests first, simple ones. Write a test, then write the code
to get just that test to work. As you make more tests work, you add more
functionality without adding anything extra. It goes against my grain
because you see extensibilities and optimizations you want to make for future
expansion or features you 'know' are coming simply because you've seen them
done that way so many times before. This is a lot like taking your past
out of your coding future, and only writing what is necessary even if it feels
incomplete. If you come to a new feature, write it down, present it to
the client, or whoever is writing the check before writing something no one may
want.
The domain side of the coin revolves around setting rules for what to and not
to write for given domains. At the core of this is
interoperability. Make no piece of code dependent upon another. If
you add an include or a using, that is all it should take. Everyone who
has written software has gone through a project where they tried to get one little
API or feature to work which required just one include. That one begat
another, which begat another, and another until you've written a state machine
for Judges in the Old Testament. Adhering to strict domains eliminates
this.
Now I am not about to call myself an expert on DDD, but I did like what I
saw. For the purposes of our example, it worked very well and I can
envision it to work well for large projects. One thing is for sure, I
will definitely be giving this new approach a few more cycles. I'll just
need the discipline to stick to it and not jump into coding before testing
which is oh so tempting.