Kerry Kimbrough wrote this a while back (again, killing my other blog), and today, I think it mostly rings true for me... except that I've always found it relatively easy to come 'up-to-speed' on a project relatively quickly via reading the codebase and learning the domain. Even with a project I'm working on now, which has an extremely confused architecture, what I needed to understand to be productive on the project and to understand how it might be rearranged to make way more 'sense'. The tests don't help much at all in this case at expressing intent, but I still think they can. And have found working at trying to make them express intent quite valuable when I have to look at them again. What I'm still missing is all the why's... especially for the decisions that aren't intuitive.
Even still, seeing the impact of no clear architectural direction and no common understanding of the design, I see what a mess it causes. And while I may be able to speed read through a code base, not everyone can do that as easily. And I have to work with those people. :) Whatever it takes to maintain that common knowledge and keep folks on the same page has gotta be much more cost effective than the impact of not having it.
--- Feb 27, 2008, Kerry Kimbrough
Janelle observed that a sign of a troubled project is an exponentially increasing cost per change over time. My response was "No, this is virtually an invariant for any software system." You can quibble if the $/change/year is really exponential, what is the coefficient, etc. But always upward.
I think this issue is much deeper and more intractable than agility vs. waterfall. Agility per se doesn’t help and may even hurt.
Here’s the problem: dissipation of the knowledge behind the system design. The system design is the result of a large number of design choices. There is a huge amount of knowledge embedded in which choices were made and, more importantly, why. In most teams, this knowledge is completely tacit, and never really exists outside the skulls of a few people. What’s left is the code itself, which typically does not capture design knowledge (only the effect of the design), much less the design rationale. The result is that every individual has to guess for himself. Eventually, none of the skulls with the original design knowledge remain on the project. The code gradually becomes the vector sum of several different design concepts, some of them confused and faulty. This increasing incoherency and resulting complexity eventually outstrips anyone’s ability to fully comprehend. $/change increases because of the increasing effort required to know how things work and why things break.
Agility hurts to the extent that it refuses to create and maintain the non-code artifacts required capture the design knowledge and rationale. Most teams fail in this difficult job, but XPers actually stand there and say you shouldn’t even try!
But the benefit of actually making the design an explicit real-world artifact is not just is holding down $/change/year. The real benefit is that the discipline of creating and maintaining this artifact leads to a better, simpler, higher-quality design. The real benefit of taking it out of the skulls and into the real world is that the whole team can learn it, share it, and improve it.
It needn’t conflict with agility. You don’t need BUFD, but you do need a design that evolves incrementally. As the tests drive the code, so the design drives the tests.