In chapter 4 "Motivation" of his book Implementation Patterns (Addison-Wesley Professional, 2008) Kent Beck cites Structured Design: Fundamentals of a Discipline of Computer Program and Systems Design (Prentice Hall, 1979) with the formula for calculating the cost of software as the sum of the cost of development plus the cost of maintaining it:
COSTtotal = COSTdevelop + COSTmaintain
The cost of maintenance is then broken down to:
COSTmaintain = COSTunderstand + COSTchange + COSTtest + COSTdeploy
I like this formula and when I recently revisited Implementation Patterns I started thinking about the cost components of software maintenance and how we work with them.
Where I work our main product is our website. Nothing else in my, and my co-workers, world really matters if the site isn't working. Since the site is there and working I tend to consider our primary work maintenance. Sure we build new features and services to improve existing or to provide new features. The development of these services might be conducted as any traditional from scratch development project. But such an individual project is just a part of the puzzle that is our site and offering. Hence I view our work mainly as maintenance. Therefore, when I revisited Kent's book I got stuck on the breakdown of cost of maintenance and asked myself these questions:
If the cost of our software mainly consists of maintenance then...
I started thinking about what we do, could, should and shouldn't do to improve on each part of the formula. How do we make understanding code easier? How do we lower the cost of change? How do we improve tests? How do we perform faster and more robust deploys? And so on. Which led me to some of the principles we apply and work by. Such as unit tests, continuous integration, infrastructure automation. At this point I'd started to draw a picture based on the formula given in the book.
Mapping out some of the principles then immediately led me to mapping out what tools and techniques we might use to support the principles. One example might be to use jUnit to support the unit testing principle.
The natural next step was to add readings and philosphies that support the above.
With the above picture it came quite natural to color code each node to visualize whether we have a certain practice/technique in place and are adhering to it, or if we're in the process of implementing it or if we hadn't even started.
My reasoning behind the node coloring is that a node representing something we do and live by is green, a node which represents something partially implemented is yellow and a node that represents something we haven't started looking at is red. A parent node may only be green if all its children are green. If any child node is yellow or red the parent is yellow unless all child nodes are red then the parent is red as well. So to finish of this example the picture could look something like this.
I think this model is a nice and concise way of illustrating what higher purpose your various tools and practices serves but also, as Kent Beck commented, it can act as a simple roadmap both to illustrate what we've done to improve in the past and serve as a backlog for what we should try improve in the future.
Thank you Kent Beck, Magnus Forsberg, Niklas Nihlén, Johan Andersson, Niklas Gustavsson and Mats Cederholm whom all took some time to read through the draft and comment.
Mårten Gustafson, 2011-09-01