Augustana University College

COMPUTING SCIENCE 220

Software Engineering and Human-Computer Interfaces


Characteristics of High-Quality Routines

Based on Chapter 5 of Steve McConnell's Code Complete



Valid Reasons to Create a Routine

Q: What is the single most important reason to create a routine?

McConnell suggests several general reasons to create routines [and we might add those in brackets below]:

McConnell then itemizes some more specific reasons. Categorize each of the following specific reasons as they relate to the general reasons above. (Some may fit well in more than one category.)

In an object-oriented context, some of these are good reasons for creating classes, while others are reasons for creating functions (operations, methods).

Q: What does McConnell say is a poor (or unnecessary) reason to create a routine? Why?

Q:McConnell suggests that, in some cases, it is even useful to create a routine for just two or three lines of code (or even for a single line). What two advantages of small routines does he cite?

Good Routine Names

Q: What format is recommended for the name of a procedure a) in a procedural language and b) in an object-oriented language?

Q: What should be used to name a function?

Give three examples of "wishy-washy" routine names (i.e., names that don't tell the reader what the routines do).

Q: How long should the name of a routine be a) according to Michael Rees and b) according to McConnell? What principle suggests that routine names should be quite long?

Strong Cohesion

Q: What is the advantage of strong cohesion?

McConnell itemizes seven levels of cohesion, outlined below in alphabetical order:

coincidental cohesion
the operations in a routine have no obvious relationship to each other
communicational cohesion
the operations in the routine use the same data (but aren't related in other ways)
functional cohesion
the routine performs one and only one operation
logical cohesion
one of several operations in a routine is selected by a control flag passed as a parameter
procedural cohesion
the routine performs several operations in a specified order (but the operations don't share data)
sequential cohesion
the routine performs several operations on the same data in a specific order (but the operations don't constitute a single function)
temporal cohesion
operations are combined into a routine because they are all done at the same time (e.g., at startup)

Q: Which is the best (strongest) kind of cohesion?

Q: Which kinds of cohesion are acceptable, and which are unacceptable?

Q: What is the difference between sequential and procedural cohesion?

Q: What subcategory of logical cohesion is acceptable? What control structure will this type of routine typically use?

Loose Coupling

McConnell lists several criteria by which we can evaluate the degree of coupling between routines:

McConnell also identifies five levels of coupling:

Q: What type of cohesion is associated with control coupling?

Q: What type of global-data coupling is "tolerable"?

Q: What is the recommended rule of thumb for the number of data fields to pass as individual parameters rather than as a large structure?

How Long Can a Routine Be?

McConnell cites the findings of several studies of the correlation between the size of routines and the cost and/or fault rate of routines. Some findings which favor longer routines are:

Other findings suggest an upper limit on routine size:

Defensive Programming

Using Assertions

In C and C++, one can use a preprocessor macro to test assertions:

    #include <assert.h>
        .
        .
        .
    assert( count > 0 );

To cause calls to assert() to be ignored at run-time, insert the following line before the include statement above:

    #define NDEBUG

In Java, Horstmann (Core Java 2, vol. 1, pp. 606-608) suggests creating an Assertion class, and controlling the use of assertions at run-time with a static final variable. (See the book for details about using inner classes instead of the static constant and function.)

    public class Assertion
    {
        public static void check( boolean condition )
        {
            if ( ! condition )
                throw new IllegalArgumentError("Assertion failed");
        }
    }
      .
      .
      .
    if ( debug )   // 'debug' is a static final variable (constant)
        Assertion.check( count > 0 );

Defensive Programming Tools in Production Code

Q: What types of defensive programming tools (code) should be left in production code? What types should be removed?

Q: What kind of internal error messages should be left in production code?