14 January 2010

What Does "Design" Mean for Software?

Most software practitioners would agree that good design is important. The trick is agreeing on what constitutes "good design." Clearly, different people will have different ideas of what is "good" -- that adjective is subjective and hard to quantify. More surprising is that there is no general agreement even on what "design" means.
When you are producing toasters, it's much clearer. The design probably comprises detailed mechanical drawings of the parts to be manufactured, an electrical schematic, and parts lists for off-the-shelf components. If you're looking at one of those artifacts, you are not likely to be confused about whether you're examining part of an actual toaster or a design for a toaster.

With software, it's much more confusing. Consequently, we have a wider range of opinions about what would be the "design" of the software as opposed to the implementation of that design (the software itself). To illuminate the problem, let's look first at a real-world example.

There are tools that will reverse-engineer the source code you have written, and produce detailed UML diagrams. In many cases, you can go both directions: make a change to the UML model, and the tool generates code for you; change the code and the model is updated. You might consider those the "as-built specifications" for your software. They are a 2-dimensional graphical model of your code structure. But is that really a "design"? You can produce the UML without ever interacting with a modeling tool, perhaps without ever sketching a single line on a whiteboard or cocktail napkin. Just point the tool at your finished code, and voila! You may have never gone through anything remotely resembling a design process, and you can still have a "UML design" view into your code.

There’s nothing wrong with using such tools if they’re useful for your project. But I would argue against automatically treating their output as a "design". In my view, there are a few key criteria that must be met before you can call something a design:
  • It reflects intentional, intelligent thought about how something should be built
  • It precedes (at least in its initial instance) the production of the item itself
  • It presents a higher level of abstraction, and offers insight beyond what you could obtain by looking directly at the end product itself.
The last bullet in that list tends to be the sticking point. When a model is detailed enough to produce the final, working code, it doesn't present any useful abstraction. It may be helpful to view the product that you have built via a graphical model, but that doesn't mean you have a design. Design is a more thoughtful, deliberative process, and must to some degree present an abstraction or idealization of reality.

The second bullet point can be controversial as well. I would contend, however, that if the artifacts a team claims to be your "design" are wholly produced after the fact, it’s not much of a design. The best claim one can make is that perhaps the original design was wholly in each of its creators' minds, but even so it would be preferable to capture those thoughts in a slightly abstracted model, instead of reverse-engineering a highly detailed model from the final production.

As we gauge the appropriate level of abstraction for software design, it is also important to consider the audience. Who will use the design, and what will they produce from it? Here, it's dangerous to follow the manufacturing analogy too far. That will be the subject of a future posting.

No comments:

Post a Comment