CPSC 333: Application to an Example

Location: [CPSC 333] [Listing by Topic] [Listing by Date] [Previous Topic] [Next Topic] Application to an Example


This material was covered during lectures on March 12, 1997.


Starting Point

Now, we'll apply the second step of ``Structured Design,'' in order to look for and correct problems in a ``first cut'' structure chart, in order to produce a usable example.

We'll continue the ``Student Information System,'' so we'll begin with the structure chart that was obtained by applying the first step.

Evaluating and Increasing Levels of Cohesion

A quick check confirms that most, but not all, of the modules in the structure chart have acceptably high levels of cohesion. Again, you can check this by considering the different kinds of cohesion in sequence, and asking whether a given module has each.

Almost every module in the structure chart seems to have functional cohesion, which is perfectly acceptable. The module ``Initialize System Data,'' shown on Page 2 of the structure chart, might only have sequential cohesion, but that's still acceptable. (Indeed, you might decide that a few of the other modules that correspond to processes on the system's data flow diagram only have ``sequential'' cohesion as well, but that's still high enough).

The module ``Old Student Processing'' shown on Page 12 of the structure chart seems to be an exception. Note that it controls three modules, ``Get Old Students,'' ``Generate Old Student Info,'' and ``Delete Old Students.'' The third of these modules should only be invoked if a control signal ``ok'' has been received, and that control signal can only generated after the first two of the modules controlled by ``Old Student Processing'' terminate, but before the third is started. Furthermore, the control signal is generated by another module in the system (shown on Page 13). Thus, it seems that it'll be necessary to call the module ``Old Student Processing'' twice, every time a set of old students is to be deleted - once to activate the first two modules, and a second time (possibly) to activate the third. It seems, then, that this module has low cohesion - logical cohesion seems to be the highest level of cohesion that it has.

First Change

In order to increase the cohesion of ``Old Student Processing,'' we'll ``factor out'' one of the responsibilities of this module - by removing the module ``Delete Old Students'' from its control, and having the module ``Delete Old Students'' controlled directly by the main module for the subsystem, ``Deletion of Old Students,'' instead. This change will require modifications of Page 10 and Page 12 of the structure chart.

Rather than simply ``promoting'' the module ``Delete Old Students'' (by moving it up a level in the structure chart), we could have ``split'' the controller ``Old Student Processing'' into two controllers - one controlling ``Get Old Students'' and ``Generate Old Student Info,'' and the other controlling ``Delete Old Students'' - and you might conclude from the heuristics for increasing cohesion that this is what to do. However, the second new controller would be ``trivial,'' so we'd end up eliminating it later on, anyway - and we'd end up with the change that's given above.

By removing ``Delete Old Students'' from its control, we've increased the level of cohesion for ``Old Student Processing'' to (at least) sequential cohesion, assuming that the system will ``delete old students'' by

in the above order.

Finally, this change will also help to alleviate a problem related to coupling between modules that will be discussed later on: Since ``Write Report to File'' (on Page 13) creates a control signal, ``ok,'' that ``Delete Old Students'' (on Page 12) apparently uses, this pair of modules has control coupling, but neither controls (appears above) the other in the structure chart. The first change doesn't correct this problem completely, but at least it does (slightly) reduce the distance between these modules in the structure chart. We'll complete this correction, when we consider problems related to coupling.

Evaluating and Reducing Levels of Coupling

Content coupling is probably something that would be introduced when modules are implemented, if at all. Fortunately, there's no sign of this in the structure chart.

The set of all the modules that access the data area (and, there are quite a few of them) has common coupling. As noted in the heuristics for reducing coupling, problems associated with this can be reduced by creating an interface for the data area, and having the (other) modules in the system call the interface functions, rather than accessing the data area directly.

Second Change

The ``Students'' data area will be turned into an informational cluster, with interface functions

Modules that formerly accessed the data area directly will now be connected to one (or more) of these interface functions, instead.

The most noticeable effects of this change will be on Page 15 of the structure chart. There will be less noticeable effects on other pages: The ``off page connectors'' at the bottom of the pages will point to slightly different places and, in a few cases, the number of ``off page connectors'' will be increased (because a module will call two or more of the ``interface functions'' that have just been created).

Several modules also do some file I/O and, depending on the level of the programming language that's to be used for coding, this might be taken to be a sign of external coupling. However, we'll assume that a high level programming language is to be used for implementation - so that the file I/O can be implemented using a small number of programming language statements, and don't introduce any dependencies we need to worry about.

Several pairs of modules exhibit control coupling, because one generates a control signal that another uses to make a decision. This is fine - as long as it's clear from the structure chart that one of the modules ``really should'' influence the other, but it's less desirable when this isn't the case - notably, when the control signal is sent up one or more levels in the structure chart, and then sent back down one or more levels again, before it can be used - because this may be a sign of decision splitting.

There are only two occurrences of this in the structure chart (after the first two changes have been made):

  1. a ``ready'' control signal is sent from ``Initialize System Data'' (on Page 2) to ``Obtain and Validate Command'' (on Page 3)
  2. an ``ok'' control signal is sent from ``Write Report to File'' (on Page 13) to ``Delete Old Students'' (which was originally on Page 12, but which was moved to Page 10 by the first change described above).
Fortunately, an inspection of the processes (and modules) involved suggests that this isn't necessary: The control signals will be used to decide whether the modules that receive them should do anything at all. Thus, it is necessary for the modules that generate the control signals to send the control signals up to the controllers that (indirectly) control both the sending and receiving modules - but it isn't necessary to send the control signals any farther than that: In both cases, the ``controller'' module can simply use the control signal to decide whether the module that ``used to'' receive the control signal should be called at all.

Thus, we've ``solved'' these ``decision splitting'' problems by moving simple decisions about whether something should be done, from a lower level module up to a module that controls it - and this is where this decision should probably have been made, anyway.

While we're at it, we'll do a bit of ``house cleaning'' (that isn't necessary, at all!) by renaming the control signals involved, and slightly changing the way they're used - so that they're used to flag unusual or ``error'' conditions. The resulting change is given below.

Third Change

The use of control signals is adjusted, to eliminate any sign of decision splitting, and so that the control signals are used to flag errors:

  1. The control signal ``ready,'' which is currently created by ``Initialize System Data'' (on Page 2) and used by ``Obtain and Validate Command'' (on Page 3) is replaced by a control signal, ``initialization failed,'' which is created by ``Initialize System Data'' (on Page 2) and sent (only) to ``Student Information System'' (on Page 1).

  2. The control signal `ok,'' which is currently created by ``Write Report to File'' (on Page 13) and sent to ``Delete Old Students,'' is replaced by a control signal ``write failed,'' which is created by ``Write Report to File'' (on Page 13) and sent (only) to ``Deletion of Old Students'' (on Page 10).

It isn't always the case that you can solve ``decision splitting'' problems simply by changing the destination of control signals, as above; sometimes a reorganization of the structure chart itself - with control connections between modules added or changed - is needed, too.

Reducing Size or Complexity of Modules

You can check for overly complex modules by drafting module specifications for them, and considering the size of these specifications. Another sign of an overly complex module, (that isn't a ``transaction center'') is ``high fan-out'' on the structure chart - which shows that the module directly controls lots of others.

There are several modules on the structure chart that look like they might - or might not - be more complex than is desirable:

Rather than making changes immediately, we'll wait until we've looked for opportunities for ``reuse;'' we'll discover that we can ``factor out'' tasks from several of these modules that they share, and create simpler utility modules that several of them call. These ``utility modules'' won't be very complex - and ``factoring them out'' will tend to reduce the complexity of the modules listed above. Thus, we'll (probably) discover that we don't need to do anything more, once these ``utility'' modules have been created and used.

Eliminating Trivial Modules

As previously mentioned, we should also be looking for - and eliminating - ``trivial'' modules. A ``controller'' that controls only one (or, possibly, two) module(s) is probably trivial and should be eliminated, especially if it calls (all of) its subordinate module(s) exactly once, whenever it is called itself.

One other module - ``Delete Old Students'' (on Page 12) - is now probably trivial (or almost so) at this point, because most of its work has been moved to one of the interface functions for the ``Students'' data area, created in the second change described above. At this point, it simply receives a set of students as input, and calls another routine (inside a while loop) in order to delete each of the received students from the system.

Fourth Change

The following ``trivial'' modules should be eliminated. Control connections should be added from the modules that used to call them, to the modules they used to call:

Now, we should be concerned about the possibility that we've gone too far at this point: We've deleted all three of the ``controller'' modules and one of the other subordinaate modules below ``Deletion of Old Students'' (on Page 10), so that this module now calls six others directly. A ``fan-out'' of six is high enough so that we should be wondering whether this module is now too complex. However, drafting a module specification for this module will (probably) confirm that it's not too complex, after all, so that in this case deletion of the controllers below it is acceptable. In a larger system, this really might have caused new problems.

Redundancy and Reuse

Several of the modules in the current system need to prompt the user for an ID number, receive an ID number as input, check its syntax, and report problems (namely, syntax errors) to the user. Since the prompts, syntax checking and error reporting should probably be the same in all cases, it makes sense to have all these modules call a ``utility module,'' ``Get ID Number.'' That is, we'll change the structure chart so that the module ``Get ID Number'' that is shown on Page 11 is called by each of the modules in the system that requires an ID number as input.

Similarly, the module ``Get File Name'' (also on Page 11) should also be called by a few more modules than it presently is.

As well, the reports prepared by ``List Registered Students'' (on Page 8) and ``List Passed Students'' (on Page 9) are probably virtually identical; we should probably create a new module, ``Write List of Students,'' that receives a set of students, ``title,'' and a file name as inputs, and have this called by both of these modules. (The format of the other reports generated by this system might be different enough for it not to be worthwhile to have this utility module used more widely than this.)

Fifth Change

``Utility modules'' are created, or existing ones are more widely used:

  1. The module ``Get ID Number'' (currently shown on Page 11) should also be called by each of the following (additional) modules:
  2. The module ``Get File Name'' (currently shown on Page 11) should also be called by each of the following (additional) modules:
  3. A module ``Write List of Students'' should be created and called by

If the system had been a bit larger then a few other useful ``utility modules'' might have been extracted as well. For example, ``Get Student Name'' could be called by ``Register Student'' (on Page 4); and could have been shared by a ``Correct Student Information'' module, if one existed in the system. It might be worthwhile to create this module, if it seems likely that a ``Correct Student Information'' command will be added to the system soon (and, this does seem to be something that's ``missing'' from the system's that been described).

This example was somewhat contrived, in the sense that the data flow diagrams refined one subsystem (with lower level data flow diagrams) in detail, without refining other subsystems very much at all. It would probably have been more realistic either to refine all the subsystems, or to refine none of them. This may have made this part of the process a bit unusual: If all the subsystems had been refined, we would probably have noticed multiple ``copies'' of essentially the same module in the structure chart (for example, ``Get ID Number'' would have appeared in several places in the structure chart for the ``Student Information System'' in this case). If none of the subsystems had been refined, then we might not have found any of the ``utility modules'' in the ``first cut'' structure chart at all, and we'd have had to look at module specifications, in order to discover common tasks that should be performed by utility modules the original modules would share.

Size and Complexity, Revisited

At this point, we've simplified almost all of the modules that we thought might be too complex; only the following are unchanged:

While these seem similar (or, at least related), there's no obvious ``common task'' that could be factored out to create a utility module for them to share.

As mentioned above, you can decide whether these modules need to be simplified (by creating submodules that they call), by drafting module specifications and checking their complexity. We won't do this (in this example) but will ``decide'' that they're simple enough already, instead.

Eliminating Unpredictable Modules

There are no modules in this system that use system state information, are nondeterministic, etc., so there's nothing to be done here.

Further ``House Cleaning''

An inspection of the data flows and control flows reveals that there are some that aren't required. In particular, none of the control flows sent by ``Choose Command Subsystem'' (on Page 3) are required - this module will call one of its submodule when a command is received, and the control flow on the data flow diagram can be modeled by this ``process invocation,'' instead of a control signal, in each case. On the other hand, the ``continue'' control signal that is received by this process is necessary, and should be retained.

A consideration of the module ``Register Student'' (on Page 4) suggests that there's no need for this module to read a ``student'' in from the data store. If this is the case (and, we'll assume that it is), then this data flow should be removed.

Note, though, that the data flow diagrams should be corrected - in this case - as well: We've found an error in the ``requirements specification'' (an unnecessary data flow), so we should go back and correct the DFDs to keep them consistent with the system that's being designed.

Sixth Change

Eliminate the control signals ``register,'' ``withdraw,'' ``pass,'' ``display,'' ``list registered,'' ``list passed,'' ``delete,'' and ``quit,'' shown as sent from the module ``Choose Command Subsystem'' (which appears on Page 3), and eliminate the data flow ``student'' that's currently shown as flowing from the data area (on Page 15) to ``Register Student'' (on Page 4).

Redrawn Structure Chart

Now that serious design problems have been identified and corrected, and changes have been made to the structure chart, the structure chart should be redrawn. The structure chart obtained by making the above changes will appear on a separate set of pages.

Location: [CPSC 333] [Listing by Topic] [Listing by Date] [Previous Topic] [Next Topic] Application to an Example


Department of Computer Science
University of Calgary

Office: (403) 220-5073
Fax: (403) 284-4707

eberly@cpsc.ucalgary.ca