Designing for Maintainability

Designing for Maintainability

More time and effort is spent on maintaining software than on developing it in the first place. Systems are compelled to change by changes in the business reality around them, by changes in the hardware and operating systems on which they run, as well as by the problems that are detected in them.

The design of a system can affect its maintainability. Indeed, the design defines not only what the system does today, but also what it can be made to do easily.

Data Driven Design

As an example, many designs are “data-driven”. That is, certain aspects of their behavior are defined not just by the code, but also by the values in tables or configuration files. The choice of what parameters are used to drive the system controls how flexible the system is.

As an example, consider a relational database management system like Access or Oracle. The tables that are created by users are defined in special tables, called data dictionary tables. So are the columns in those tables, the indexes to be used, the constraints, etc. The fact that employees have phone numbers is not defined into the code of the database management system (i.e., it is not “hard-coded”). Instead, that is driven by the data. So is the fact that there are employees at all

On the other hand, the fact the all information is stored in tables is defined by the code itself.

Most systems are not as data driven as a relational DBMS. The applications that use them, for example, may well hard code the fact that employees exist, and have phone numbers. If the application is the product of a vendor, it may yet define in data whether North American style phone numbers are used.

Even in custom applications developed for one company, there is value in driving some of the processing from data. The classic rule of thumb (somewhat joking) is that the designer should not believe business policies, but only laws of nature.

Trade-offs

As a general rule, driving behavior from data introduces at least some overhead, and thus makes the performance worse. It can, however, dramatically reduce the costs and schedule of producing the next version.

The performance impact may be more important for heavily loaded systems, or systems that will be run in many copies on many machines.

On the other side, flexibility is going to be more critical for systems that will frequently change along the predicted paths, or which may need to do so very quickly.

YAGNI

All of this assumes that the designer can reasonably project the paths along which needs for the system might develop.

For some business areas, it is hard to predict what kind of changes may be required. This was particularly common during the early days of Internet development, when the marketplace itself was changing very rapidly.

Developers in those and similar environments came to feel that designing for flexibility and maintainability was useless, since the paths they left themselves to change frequently turned out to be ones they did not need. These early pioneers of agile methods felt that you should just build what you knew that you would need now. Of the rest, they said “You Ain’t Gonna Need It” (YAGNI).

These approaches worked very well in environments where the systems were adequately small, and which had lower needs for reliability.

“Good” Design

In each of the major approaches to software design, there are guidelines for identifying approaches that are in some sense superior to others.

These guidelines tend to ensure that the components of the design combine things that “naturally” go together.

In functional design methods like structured analysis, the goal is to have components that represent natural functions. One of the rules of thumb for such a function is that it can be expressed in a single sentence without conjunctions (and, or, but).

For example, Print The Report is a good function, while Calculate The Tax and Display The Bill is not. The second function won’t be easily reused in cases where you need to do only one of those functions. You are better off dividing it into two functions.

A similar idea applies to object oriented design. The classes should represent natural objects. If you can’t come up with a really descriptive name for the class as a kind of object, maybe it is a bad one.

Component Complexity

If you break a design down into too many components, it will be hard to follow the logic. You will have to look from component to component to understand what is happening.

If you don’t break it down enough, it may also be hard to understand. Too much may be going on in one place.

Tom McCabe defined the Convolutional Complexity Metric to try to determine when a component was too big. This metric starts at 1 for a program without branching. It adds one for every alternate branch. Thus an If statement adds 1 (for the Else branch, even if it doesn’t do anything), as does a While or Repeat or For statement. A control statement with multiple branches (like a switch statement) adds 1 for each branch beyond 1 (including the default, whether specified or not).

McCabe claimed that when is metric was too small (say 3 or less), the component was typically too simple. When it was too large (over 10), the complexity led to extra errors.

Carma McClure extended this idea by counting not branches, but conditions.

Design Decay

Over time, changes that were not anticipated in the structure tend to make the structure of the software more convoluted and less logical. This “decay” makes it harder to train maintainers. It makes it harder for them to figure out what is affected by changes. It makes problems harder to root out.

As we will see when we look at maintenance, this drives up the costs of software maintenance, and reduces its reliability. There are approaches in the maintenance world to restore the integrity of the design, but they require significant effort. In the agile world, it is considered normal and desirable to refactor (or restructure) the design on an ongoing basis. That is one of the limiting factors on the size of agile projects, since the cost of restructuring grows rapidly with the size of the system.

To view or add a comment, sign in

More articles by Gary Page

  • The Mighty Warrior Models Classes

    The Mighty Warrior Models Classes The mighty warrior reached into her pack, and pulled out her favorite weapon, the…

  • What Data Should I Store: Database Design

    What Data Should I Store: Database Design Once the question of what database management system should be used is…

  • What Do I Need in a Database?

    What Do I Want In A Database? I once took a day off from my normal activities at my work to help my wife’s employer…

    1 Comment
  • Getting It Done Quick and Cheap

    Getting It Done Quick and Cheap What do you do when your boss says, “That is just too long!” or “We can’t afford…

  • My Neighbor Bob and The SDLC

    My Neighbor Bob and the SDLC One evening on the way into the house, I talked to my neighbor, Bob. In the course of our…

  • Good Requirements

    Good Requirements In order to build a system or business process to do what your company needs, someone needs to write…

  • The Mighty Warrior Gathers Information

    The Mighty Warrior Gathers Information Her long raven tresses cascading down the back of her silver armor, the mighty…

    1 Comment
  • The Information Factory

    The Information Factory Several years ago, I was working for a client who needed help planning an internal network. My…

  • Draining the Swamp

    Draining the Swamp When we try to simplify business processes, and make things more efficient, we are often surprised…

    1 Comment

Explore content categories