Sunday, July 1, 2007

Software Engineering Analogies

I have seen many comparisons to software engineering that like to make software development fit into the engineering metaphor. Sometimes it goes like this, a software engineer designs the software and then passes it on to a programmer to implement. The analogy is that software is like constructing a building or a bridge or something like that. The architect or engineer doesn't do the construction of the building therefore the software architect doesn't do so either.

It sounds good and it actually does work. However, almost all software isn't developed using this "sound" method. Why?

Because it doesn't work that way. A whole industry of software engineering methodology is based off of the assumption that the analogy is correct. Which makes a lot of software engineers and non engineers who read this stuff think that the way we develop software is wrong. This doesn't do anybody any good. Often you get people outside of the development team telling you that your methods are wrong. When or if you try to apply these methods they tend to cost too much and don't get significantly better results. In some cases the results are worse.

I submit there is a better analogy. In order to understand the analogy, we need to first understand what the end product of a software engineer is.

Most people will state the obvious, the end product is the executable. It might be an embedded system that runs a cell phone, or a sales contact management database or a software program like the web browser you are using.

While this is the deliverable of the company producing the software, it isn't the deliverable of the software engineer. The software engineer delivers code that can be compiled into the final product.

So what does an architect deliver that is designing a building? Not the building. The deliverable is the working drawings. They stick with the process through construction and continue to fix the drawings as problems during construction are identified.

If you haven't guessed already analogy I like is that the software engineer is like an architect. Just as an architect interfaces with customers to define the requirements for a building, the software engineer also interfaces with customers to define the requirements for the software. Just as an architect will iterate through several designs working with pen and paper or a CAD system a software engineer does the same. The working drawings can be reproduced at will, just like software.

This analogy makes a lot more sense when you realize that most software is implemented by the designer of the software. This works really well when there is just one person and when you are working in a small group of engineers. It also scales pretty well to larger groups, but does rely on more documentation to keep everyone on the same page.

In any case, I think if you start your analysis of how to develop software with a faulty analogy, you get faulty results.

Assuming you accept my analogy that a software engineer is like an architect, an examination of how architects work would be in order. In fact when you look at this model you find that most of the stuff that an architect does a software engineer also does. You interface with your customer, you show them preliminary designs, you take feedback and iterate on them.

It is just as easy to change a CAD drawing as it is to change software so iterating on the software is something that can be done. Just as architects leverage building blocks like CAD details that they have placed into a library a software engineer leverages code reuse.

Another aspect of this is that an architect needs to make all the working drawings in a set look consistent even if several people are working on them. Have you ever had trouble with a team member not sticking to coding standards because they liked their style instead of the team standard?

It starts getting you to thinking, if the end product is the code, then there should be some pride of workmanship in the code. A mechanical engineer designing a high end car will spend a lot of time making the engine compartment easy to work on and to some extent it will be a work of art. If you ever get a chance it is interesting to take a look at the large steam engines that Henry Ford used in his factories. These aren't ugly, they are works of art.

If you look at code and it looks like it went through a blender, you can tell the person who wrote it was less concerned with the implementation than simply getting the job done. Back to a set of architectural drawings. A sketch on a napkin may suffice for a very simple project, like building a deck, as long as you are the one doing the construction. But the more complicated the design and the more people involved, the more accurate and clear the working drawings have to be.

Another consideration is the idea of writing in pseudo-code. This is useful if you are going to be writing in assembly, but these days our languages are more expressive, readable and precise than pseudo-code. I liken this to writing the outline of an English novel in French. The same idea applies to other tools like UML etc. While I do believe UML has value when communicating with someone who doesn't understand the language you are writing in, it really doesn't help a lot when communicating to a expert in the language.

Don't look to hard at this analogy or you will start to find cracks in it. As with all good analogies, they break down after a certain point.

So the next time you think about software engineering, think about the architect.

No comments: