The Code is the Design, Baby!

What exactly is the “design” of a software system? Is it a detailed UML diagram? Is it 300 pages of prose? I recently came across an article from 1992 by Jack W. Reeves, mentioned in an interview on the subject of TDD; in his article, Jack argues that the design is actually the source code itself.

What!? The code is the design? This proposition is surprising at first, but not really if you think about it: only the tested and debugged code is a precise description of how the system should behave, how it should be built. And the process of “building” a software system is merely the feeding of the code to tools like make, Ant, compilers and linkers. Thus, “designing” software is hard, building software is straightforward.

Often, people demand that the design should be a UML diagram, something that is easy to read and comprehend by anyone. However, for any non-trivial system, the diagram(s) would become at least as complicated as the real code. It’s always the same: you start out with a couple of classes that have only a few relations, and everything looks nice; but when you finally have 200 classes you suddenly cannot see the forest for the trees anymore. UML is good for highlighting certain parts and aspects of a system, but a complete specification, one that can be handed down to the “code monkeys” is a myth. Even the author of the most successful UML book ever, Martin Fowler, is very skeptical about UML as a blueprint design tool. As Fred Brooks pointed out long ago: “software is not inherently embedded in space and has no ready geometric representation” (like hardware or buildings do).

There are technical issues, too. How do multiple “designers” collaborate on a UML design? How do they create parallel versions and merge conflicts? How do they keep track of variants? Countless tools exist for designs based on plain-text (aka. source code); next to nothing exists for UML.

Why do so many folks fall prey for this “everything-has-to-be-designed-in-UML” idea? Some (most likely managers or sales people) simply confuse programming with typing. Others (most likely developers that never got the hang of programming), want to introduce a white-collar/blue-collar developer system. Yet others think that there must be a method (in this case UML) that would render a complex system in such a way that it can be understood fully by anyone (including managers, sales people and developers who never got the hang of programming).

The design of a modern airplane comprises hundreds of thousands of pages. Nobody can and must comprehend everything. But even laymen can look at the 3D model and understand a lot: ah, this is where the engines are, and yep, here we have the anti-lock brake system and, boy-oh-boy, here we have the flight controller.

Such design overview diagrams are very important for comprehension and communication and no source code can ever replace them. It’s important to have such a diagram (call it high-level design or system architecture diagram or whatever you like). If you want, you can draw it in UML but I suggest you don’t: UML is way too boring. Have a look at the Google Android architecture diagram — it’s shiny, it’s been reduced to the absolute minimum, it’s freakin’ awesome!

Is there a need for designers, anyway? I definitely think so! You need somebody who takes care of the big-picture technical decisions, like the high-level composition of a system, the coding conventions, the hardware decisions and so on. Let’s call this person the systems architect. And, of course, you need somebody who takes care of the look & feel, the user-interface, a Steve Jobs kind of person. And, last but not least, you need many small-to-medium scale “designers” who iteratively detail the “design” through so-called “programming” such that compilers, linkers and the like can build the rest easily.