Going modular? Meet data and control coupling

CODE QUALITY BLOG: Since the dawn of the discipline of software engineering, one of the persistent mantras has been modularization. This structured design and functional decomposition approach breaks software down into clearly defined functional units, or modules, with unambiguous interfaces. The proven value of this approach is high quality software. When you go modular, however, software testing must examine the way that the modules come together and interact. This kind of testing is dubbed “data and control coupling.”

Today, let’s get a handle on how the control and data coupling within a software system can be used to assess the modularity of a system and provide invaluable benefits including:

• Improving software testability
• Improving software maintainability
• Reducing the impact of change
• Simplifying

The term ‘cohesion’ describes the properties of a modular software component. A module that has well-defined interfaces and that operates independently of other modules is considered to have high levels of cohesion. For example, a command line MD5 hash generator is an example of a software component that demonstrates high levels of cohesion. The input is a data object of any description (e.g., a file), and the output is a base-64 hash representation. Because the hash generator takes a single input, provides a single output and has no external dependencies, it is considered to demonstrate high levels of cohesion.

At the other end of the spectrum is a . These are highly dependent on the current state of the plane (e.g., is the aircraft on the ground) and an incoming flight (e.g., air speed, altitude, attitude, etc.), so therefore has low levels of cohesion.

Cohesion significantly affects anyone who has tried to extract a software module from one system for reuse in another, and they’ll be happy to tell you war stories about hidden dependencies that got in the way. And herein lies the problem: if modules are not truly cohesive, then how is it possible to test each module in the context of all of its dependents? To achieve this, you have to understand the coupling that exists between software modules. This coupling provides a means of measuring software cohesion and also provides metrics that can be used to assess and improve software quality.

The concept of coupling was defined in the 1980 book “The Practical Guide to Structured Systems Design” by Meiler Page-Jones to be “the degree of dependence of one module upon another; specifically, a measure of the chance that a defect in one module will appear as a defect in the other, or the chance that a change in one module will necessitate a change to another.”

He identified two fundamental flavors of coupling and defined them as:

• control coupling—a type of coupling in which one module communicates information to another module for the explicit purpose of influencing the latter
• data coupling—a form of coupling in which one module communicates information to another

Let’s look at an example to clarify the differences between the two.

An aircraft engine control system consumes information such as altitude and airspeed, but there are different control algorithms used when the aircraft is on the ground versus in the air. The choice of which algorithm to use is determined by a “weight on wheels” signal from the landing gear systems that indicates whether the aircraft is on the ground or not. In this example, the dependence of the engine control system on the altitude and airspeed data streams indicates a strong data coupling with the systems that provide them. Similarly, the “weight on wheels” signal indicates strong control coupling between the engine control systems and the landing gear systems.

Coupling metrics can be used to improve software quality throughout the software design and verification process. The intent is to show that the software modules affect one another only in the ways intended by the software design, ensuring that there are no unplanned, anomalous, or erroneous behaviors. Documenting data and control coupling during design provides a set of requirements to test during the software integration process. Similarly, ensuring that the data and control coupling between modules are exercised during software test demonstrates that the integration and architecture of the software is fully verified.

Many guidelines, such as the standard that defines the airworthiness regulations for the creation of civil airborne systems, require that a control and data coupling assessment be performed on safety-critical software to ensure that these design, integration, and test objectives are met. Similarly, the UK Ministry of Defence Standard 00-55 “Requirements for Safety-Related Software in Defence Equipment” requires that metrics, such as control and data coupling, be used to assess software modularity.

Measuring control and data coupling is achieved via a combination of control and data flow analysis. Control flow analysis is performed both on a programs calling hierarchy and on individual procedures.
Data Flow Analysis follows variables through the source code and reports any anomalous use. This check is performed both at the procedure level and as part of system-wide analysis. It is a very powerful technique that, not only provides the basis for a data coupling assessment, but also detects other serious problems, such as variables that are used before they are initialized or an array that is accessed outside of its bounds.

Although it is easy to assume from the naming that control flow analysis provides visibility of control coupling and data flow analysis of data coupling, this is not the case. Both control flow and data flow analyses are necessary for assessing both control and data coupling.

Whether the software under development is safety critical or not, measuring the cohesion of software modules via control and data coupling helps to yield improvements in software testability and maintainability while reducing the impact of change, simplifying software reuse.