Dealing with Changes: Using Functional Decomposition

Average rating
(0 votes)

Using modularity to isolate variation

Example 1-1. Using Modularity to Contain Variation
function: display shape
input: type of shape, description of shape
action:
switch (type of shape)
case square: put display function for square here
case circle: put display function for circle here

Problems with modularity in a functional decomposition approach

Then, when I receive a requirement to be able to display a new type of shapea triangle, for instanceI only need to change this module (hopefully!).

This approach presents some problems, however. For example, I said that the inputs to the module were the type of shape and a description of the shape. Depending upon how I am storing shapes, it may or may not be possible to have a consistent description of shapes that will work well for all shapes. What if the description of the shape is sometimes stored as an array of points and sometimes is stored another way? Would that still work?

Modularity definitely helps to make the code more understandable, and understandability makes the code easier to maintain. But modularity does not always help code deal with all the variations it might encounter.

Weak cohesion, tight coupling

With the approach that I have used so far, I find that I have two significant problems, which go by the terms weak cohesion and tight coupling. In his book Code Complete (Microsoft Press, 1993), Steve McConnell gives an excellent description of both cohesion and coupling. He says:

Cohesion refers to how "closely the operations in a routine are related."[1]

[1] McConnell, S. Code Complete: A Practical Handbook of Software Construction, Redmond: Microsoft Press, 1993, p. 81. (Note: McConnell did not invent these terms, Yourdon and Constantine did. We just happen to like his definitions best.)

I have heard other people refer to cohesion as clarity because the more that operations are related in a routine (or a class), the easier it is to understand things. Weakly cohesive classes are those that do many, unrelated tasks. The code often appears to be a confused mass. Taken to an extreme, these classes become entangled with most everything in a system. I have heard some people call these god objects, because they do everything (or perhaps it's because only God can understand them).

Coupling refers to "the strength of a connection between two routines. Coupling is a complement to cohesion. Cohesion describes how strongly the internal contents of a routine are related to each other. Coupling describes how strongly a routine is related to other routines. The goal is to create routines with internal integrity (strong cohesion) and small, direct, visible, and flexible relations to other routines (loose coupling)."[2]

[2] Ibid, p. 87.

Changing a function, or even data used by a function, can wreak havoc on other functions

Most programmers have had the experience of making a change to a function or piece of data in one area of the code that then has an unexpected impact on other pieces of code. This type of bug is called an unwanted side effect. That is because although we get the impact we want (the change), we also get other impacts we don't wantbugs! What is worse, these bugs are often difficult to find because we usually don't notice the relationship that caused the side effects in the first place. (If we had, we wouldn't have changed it the way we did.)

In fact, bugs of this type lead me to a rather startling observation: We really do not spend much time fixing bugs.

I think fixing bugs takes a short period of time in the maintenance and debugging process. The overwhelming amount of time involved in maintenance and debugging is spent on trying to discover how the code works and on finding bugs and taking the time to avoid unwanted side effects. The actual fix is relatively short!

Because unwanted side effects are often the hardest bugs to find, having a function that touches many different pieces of data makes it more likely that a change in requirements will result in a problem.

The Devil Is in the Side Effects
A focus on functions is likely to cause side effects that are difficult to find.

Most of the time spent in maintenance and debugging is not spent on fixing bugs, but in finding them and seeing how to avoid unwanted side effects from the fix.

Functional decomposition focuses on the wrong thing

With functional decomposition, changing requirements cause my software development and maintenance efforts to thrash. I am focused primarily on the functions. Changes to one set of functions or data impact other sets of functions and other sets of data, which in turn impact other functions that must be changed. Like a snowball that picks up snow as it rolls downhill, a focus on functions leads to a cascade of changes from which it is difficult to escape.