I met with a Fujitsu executive last week, and we naturally got onto the topic of software development methodology. I presented my case that it is critical that programmers know the actual customer because 90% of all decisions that effect usability are made by the lowest programmer. He countered with a story from his own experience of how a race car mechanic and driver have to work as a team.
He explained that he used to drive race-cars before joining Fujitsu. The driver and the mechanic are both critical to winning a race. The driver experiences the car in one way, while the mechanic experiences the car in a completely different way. The driver can not adjust the engine, and the mechanic can not drive the car. The driver and the mechanic have to develop a way to communicate about the performance of the car. The driver will describe the experience, the mechanic will translate this to what it might mean for the machinery of the car. The mechanic might make an adjustment, and see how the driver reports the change. Over time they will develop a special language to talk about how the car is performing, and how performance might be improved. They iterate in order to perfect this language.
What I like about this story it that it emphasizes teamwork along with clear specialization of duties. Having the driver adjust the engine is pointless, and having the mechanic drive the car is equally pointless. There is no short cut: they have to collaborate, and they have to find that common language in order to do it.
He employed this as an analogy for software development: there is the role of the designer architect and the role of the programmer. The designer architect understands the customer and has to learn how to communicate to the programmer who tweaks the product. Each specialize in their domain, and work together to make the final product.
Sounds good, but for one thing: complexity. Much of what we do in software involves ways of coping with overwhelming complexity. How complex is car-racing? Consider the degrees of freedom that a car driver has: accelerator, brake, gear, steering, speed, acceleration, turning rate, etc. Possibly 10 dimensions to play with. While cars seem complicated, they have between 5000 and 15000 parts. Within the engine, there are again only a few controls, possibly 10 different ways to control the engine performance. More and more the engine is controlled by software, but make no mistake: in the end there are only so many ways the engine can be tweaked.
The complexity of a typical large software program is a thousand to a million times more complex. While a car may have 5000 parts, many of those parts are very simple, like a bolt or a nut, and duplicated many times identically. However, a million line program, each part of that program is unique, and infinitely variable. A single method (subroutine) may be called from hundreds of places, but that method is not duplicated in any way analogous to how small parts are manufactured for a car. The physicality of a car engine forces the designers to limit the size and number of parts but since software has no physicality, the collection of parts of the program can grow without limit and without significant (direct) cost.
The thing about highly complex systems is that approaches that work for small examples simply don’t scale to the large scale. Usability is about many very very small things. It is easier to write a program, than it is to write a document to describe the program. If a designer architect was to communicate about every button, every gesture, on every screen, there would not be enough time in a century to cover a modestly complex program. It is certainly true that the high level goals of the program can be communicated in the same way as the driver/mechanic do. But “usability” requires an understanding of the customer, how the customer is going to use it, and what the customer values are, by the actual programmer who writes the code. There are thousands of detailed decisions that a programmer makes; if made correctly the customer loves the final product, but made incorrectly the customer hates the solution, even if it meets every specified requirement. To address this, agile software approaches do two things: seep the development team in the culture of the customer, and do many rapid iterations so that the customer can see it as it develops, and provide early feedback to correct the course. You set up feedback loops that are fractal in nature, and work at all levels to improve the final product, including usability.
I like the story of the driver and the mechanic, but I fear it mainly confuses people by trying to take “hardware thinking” into the software realm. In complexity circles, it is well known that “wicked problems” are not solved by scaling up an approach to a small example. While it is certainly true that there are many roles that professionals need to play, and they do need to specialize, and learn to communicate, however this does not mean that you can eliminate the need for programmers to understand the customer. Particularly if you want a product that customers love to use.
P.S. Reviewing a great new book by John Gøtze et. al. called Beyond Alignment which has many articles about approaches to Enterprise Architecture that try to address the extreme complexity of organizations. Look forward to a summary, soon.