Emerging design
I’ve been thinking about how, when programming, a design emerges if you just let it – that is, if you don’t pay any or only little attention to it upfront.
The project I and my friend Malte are working in is in the phase of implementing accounting. Neither Malte nor I had any prior experience with double entry bookkeeping and the business rules regarding this were very fuzzy, so the task at first seemed very difficult (to me at least).
However, trying to be as much XP as possible, we wanted to start coding (or rather, start testing) as soon as possible, instead of burying ourselves in the details of double entry bookkeeping or trying to disentangle the business rules.
So, we started with what we knew to be true, wrote a tiny first test for that, made it pass, wrote another tiny test, and so on, following the XP guidelines of never writing a line of code without a failing test and testing everything that could possibly break.
After doing this for about two weeks now, we can observe a few things. Firstly, we have a very powerful design which expresses the business rules very clearly and is simpler than we ever would have thought. When we pick the next thing to implement from the to-do list, the design allows this to be done in very few lines of code.
Secondly, it’s interesting to see how a vocabulary have emerged. Our being Swedish, we’re not a 100% sure that it is correct English, but that’s not really the point. The important thing is that it is intuitive, simple and effective. For example, we talk about a group of {Processors} processing a set of {Brokerage Lists}, producing {Documents}. A particular {Processor} is the {Voucher List Builder}, which produces a {Document} containing a list of {Vouchers}, which are {consolidated} for each combination of {account number} and {cost unit}.
The vocabulary expresses the architecture, which also has emerged during these two weeks. When we make additions, we do so according to our architecture. For example, if a new document should be produced, that would be done by subclassing Processor and adding it to the ListRunner (which itself is a Processor subclass).
I’m convinced that doing this step by step and trying to keep the concepts clear (and therefore keeping the vocabulary clear) has resulted in a design and an architecture that are clear and concise and that allow themselves to be evolved gracefully. I’m also convinced that designing and architecting this before coding would have taken more time and not produced as good results. This has been a successful experiment.