May 19, 2004

The Need for Software Design...

Here is a novel idea: let's Design software before coding. Quick, let me patent this!

I am obviously joking here, or at least partially. Why is it that many people do not invest time in designing prior to coding?

Surely, part of the reason behind this is schooling. For a moment, think about your Computer Science's Software Engineering course (if any). What do you remember of this course? Most people that I have asked tell me essentially the same answer. Most people think that Software Engineering is important, however, when you learn it in school, there is not enough hands on experience and it is hard to understand everything the entire development process without the experience1. You learn about all the techniques in sections, but you do not get to use them in a real work environment and as a whole.

I also think that another part behind it is that everyone and their mother is a Software Engineer. I mean, many developers have degrees in a variety of disciplines, and for one reason or another, upon graduation became Software Developers. This is not to say that they are not qualified to be developers, but rather that certain processes have not been introduced to them. This is more related to my wife's same comment regarding graphic designers, in which everyone thinks that they can design their own stationary, business cards, newsletters, and what have you, but you can easily tell the difference between an amateur and something that is not.

But in reality, it has very little to do with the degrees that people have, but it also has to do with the person, and to this end, I think some developers are simply developers for a job and do not have a passion for the job. To me, I say that I am a software developer as a lifestyle choice. I choose to keep up-to-date on a variety of magazines, books, toolkits, and various other web sites, and I do so on my personal time with my own money. Recently, I was talking with some friends, and I mentioned the ACE Toolkit, and to my surprise, many blank faces were before me. While I realize that ACEtm is a specialized toolkit, I find it hard to believe that few of the people I talked with knew something about it. It is something that is advertised, has at least three books on it, and well, I think it takes more than familiarity with Networking and C++ to know it, and it is definitely a toolkit to consider as a component.

In this regard, components, design patterns, and algorithms are all elements that help us design and create better software and really a part of Software Engineering. Recently, I attended a conference in which someone asked, "How many of you own the Design Patterns2 book?" To little surprise, almost everyone in the room raised their hands. Then the same person asked, "How many of you have actually read the book?" Not surprisingly, most of the hands were down. Toolkits and, more specifically, components allow you to reuse code, which saves on development time. Design patterns and algorithms provide us with the experience of many developers before us. There is little reason to reinvent the wheel, and by building onto this experience, we can concentrate our energy on bringing software to the next level.

Returning back to the original topic of why design is not done, a lot of this is experience based. Most school based projects are small enough where design is not required by the teacher and can basically be done with a little or no planning. And some projects simply follow this theme.

I think that a last reason that design is not done is because people believe that it is hard. In this regard, there are many design schemes that you can do, and that all depend on what exactly you are doing. Some design methodologies are extremely involved, however, there are many lightweight methodologies available. Besides, the more that a task is done, the easier it gets.

An issue with software engineering in general is shared vision. A group of software developers cannot work in isolation to create an application. Communication must exist between these developers to ensure that everyone is building the correct tool and leverage out the components used in other modules. A design can help with this shared vision, by instilling a picture of the end goal. Each time that a person describes a feature, the feature has a different scope. The design keeps the scope and details unified. But this being said, it is important that people read, review, and discuss the design, because without these elements, no everyone understands the problem in the same fashion, and there is no shared vision.

Linus Torvalds is not exactly in favour of Design, claiming that it has made some software inflexible. But I tend to agree with Joel on Software when he says, that Nothing is as Simple as It Seems, and some design is required. By investing some time thinking before typing, you can explore some different avenues and know some of the advantages and disadvantages of the approach of your choosing. By keeping a record (perhaps in a plog?), other developers can both provide useful feedback to your design and others can learn from your design.

Any level of design helps newly hired software engineers to get up-to-speed on your product much faster. Experienced engineers will notice the architecture and see how components interact. But even existing engineers can benefit from the design in the same way. Most developers do not know the entire code base, and the design will allow them to be brought up to speed faster. Furthermore, in adding new features to a software, it is easy to forget some feature or specialization that the software has. Referring to the design will ensure fewer surprises in the development of the feature.

Keeping the design synchronized with the code, however, can be difficult in some cases, however, tools are available to assist you in this task and updating your design needs to be part of your process. Even in this regard, modern integrated development environments come with design tools, so this argument becomes less and less of an issue.

I have started reading The Inmates are Running the Asylum, and the book has some great quotes. In support of design, Alan Cooper states, "We can create powerful and pleasurable software-based products by the simple expedient of designing our computer-based products before we build them." Alan's book is talking primarily about user interfaces, but this one comment is really about the entire product. There are many places that it is said, for example, that you cannot add security to a product; it must be designed in the product from the start. This relates to software user interfaces, coding style, and a variety of other software-engineering topics.

Everyone is familiar with the broken-window theory, from Andrew Hunt's and David Thomas's The Pragmatic Programmer: From Journeyman to Master. If your components do not have design, when you have to add something to them, most developers are not going to invest the time in modeling the current product, and then adding the new functionality. In most cases, this occurs because the new functionality is easily added to the existing product.

In this regard, I believe this is what is happening at a great deal of software companies. The products were not designed at the very start, because of experience, time/schedule, its a prototype, or what have you, and no one ever takes the time to rectify this problem. In many cases, this can turn into a re-write of the product, which eventually turns into a Death March.

Because of the lack of software design, software planning becomes difficult. The schedule is essential made based on guesses of what has to be done, but the reality is, no one knows what must be done. Tasks and time to complete those tasks are somehow created, and part of this will be right. All to often, however, some of the items are under estimated by significant amounts, new tasks are "discovered", and some things are just forgotten.

Schedule problems can be resolved by having developers work more hours, adding developers, and/or adding time to the end of the schedule. The first option of having developers work more hours usually does not work. Books such as Debugging the Development Process by Steve Maguire, tell you that developers can be productive for around 50 hours a week maximum. Besides, one of my friends recently told me that you have to be at work for 40 hours, but you do not have to work for 40 hours, and this is supported to an extent by articles like Joel on Software's Fire and Motion.

Adding more developers generally does not help the situation, as the new developers require training, which takes time from the other developers, which does not help the project. This is covered in Death March.

Probably the only way to resolve scheduling problems is by adding time at the end of the schedule, but unfortunately, this is rarely an option. Features are generally dropped, or one of the previously mentioned items are attempted.

On the other hand, schedules that are too strict are not good either. I regularly listen to requests from our customers regarding problems that they have or features they would like to see. Some books, such as Software Engineering recommend that you develop the features they requested and also add some helpful features into the software to simply wow your customers without telling them. This has the benefit of making the customer having a new connection with the software, and so, when a customer tells me of a problem or asks me for a feature that is not too difficult to implement, a non-strict schedule permits a developer to implement these features. Such features, however, do require some effort on the SQA group, and therefore, need to be known about.

It is only fitting, I think, that if developers fail to design their creations, that they equally fail to test their creations, another one of those steps in most software engineering models. All too often, I see new classes being added, without a single comment or a single test program. How do you know that this works? How do you even know what it does? You do not. If you have no design, at least use adequate comments. All too frequently, I create a class that appears to work great in my target application, however, when I develop some unit tests using JUnit or boost, it is rare that I do not catch some problems that I would not have have caught otherwise. As the saying goes, if you do not test your software, your customers will.

Fortunately, as Alan Cooper points out, people can, however frustrated they are with your software, overlook the bad points of software if it does something useful overall. Unfortunately, this is the norm...

[1] This is one area where a non-traditional degree, such as the one offered by ACCIS, can be beneficial, in the proper environment).

[2] Gamma, Erich, Richard Helm, Ralph Johnson, John Vlissides. "Design Patterns: Elements of Reusable Object-Oriented Software." Addison-Wesley-Longman, 1995.

Filed In