Dealing with Changes: Using Functional Decomposition

Look a little closer at the problem of displaying shapes. How can I write the code so that it is easier to handle shifting requirements? Rather than writing one large function, I could make it more modular.

For example, in Step 4c on page 4, where I “Call appropriate function that will display shape, giving it the shape's location,” I could write a module like that shown in Example 1-1.

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

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

There are some problems with this approach, 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? 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 of the variation it might encounter.

With the approach that I have used so far, I find that I have two significant problems, which go by the terms low cohesion and tight coupling. In his book Code Complete, 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, we just happen to like his definitions of them 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.

  • 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.

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 while we get the impact we want (the change), we also get other impacts we don't want—bugs! 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 spent in maintenance and debugging is on finding bugs and taking the time to avoid unwanted side effects. The actual fix is relatively short!

Since 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.


With functional decomposition, changing requirements causes 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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.121.209