The goal of Appaserver's developers is to
conform to the development methodology established by
Glenford J. Myers
*.
Myers ranked the idea of
module
cohesion the degree of interaction within a model
and module
coupling the degree of interaction between modules.
Cohesion
The quality of a module's function determines the level of cohesion.
From worst to best, here are the levels of cohesion:
- Coincidential Cohesion is a module that
performs two or more unrelated functions. Evidence of this occurs
when a function name cannot be defined.
- Logical Cohesion is a module that
has available a series of functions, but only one
of the functions is executed. This is the result of
the case statement. Myers contends that this degrades
readability, resulting in having to inspect the function
to determine what is going to happen.
- Temporal Cohesion is a module that
performs a series of functions because it's time to.
This usually occurs at the beginning of the algorithm,
like calling the function perform_initialization().
- Procedural Cohesion is a module
that performs multiple functions, but only loosely related.
An example would be the function
read_part_number_and_update_employee_record(), where the
employee record has no need for the part number.
- Communicational Cohesion is a module
that performs multiple functions, but closely
related. An example would be the function
read_part_number_and_update_sales_record(), where the
sales record would need the part number.
- Informational Cohesion is a module
that performs multiple functions, and each function
has its own entry point. However, all of the functions
work on shared variables.
The C++ class structure works at this level.
- Functional Cohesion is a module
that performs exactly one function. Or in the case of a module having
multiple functions, each function has its own entry point,
but works only on local variables. The goal is to be
able to reuse the function in any context.
Coupling
Modules interact with each other via function calls, passing information
back and forth. The degree of information passing sets the level
of coupling.
From worst to best, here are the levels of coupling:
- Content Coupling is when a function modifies
a variable local to another function.
- Common Coupling is when a function modifies a
global variable.
- Control Coupling is when a function tells
another function where to go. Difficulty occurs because the modules
are no longer independent of each other.
- Stamp Coupling is when a function receives an
entire structure as a parameter. This is how the FILE Abstract
Data Type behaves. Whereas stamp coupling saves typing, flexibility is
lost.
- Data Coupling is when each data element is
presented in the parameter listing individually. This allows
for greatest flexibility and readability.
The ideal function should have only input parameters and
return a single value. However, for CPU efficiency, sometimes
it is necessary to return multiple values. If multiple return
values are necessary, pass the address of the variables
to the function starting at the first parameter position.
The developers of Appaserver®
attempt to achieve Functional Cohesion and Data Coupling with the
construction of Abstract Data Types (ADTs). Each object is represented
with a data structure, and all of the corresponding operations are
contained in the same source file. Moreover, the syntax for each operation is
ObjectName_SomeVerbPhrase_ReturnDatatype( parameter list );
For example:
/* firm.h */
/* ------ */
#ifndef FIRM_H
#define FIRM_H
typedef struct
{
char *firm_name;
/* Firm's other attributes */
int firm_zip_code;
} FIRM;
/* Operations */
/* ---------- */
FIRM *firm_new_firm( char *firm_name,
int firm_zip_code );
double firm_get_distance_miles_double(
int firm_zip_code,
int residential_zip_code );
#endif
/* firm.c */
/* ------ */
#include "stdio.h"
#include "firm.h"
FIRM *firm_new_firm( char *firm_name, int firm_zip_code )
{
FIRM *firm = (FIRM *)calloc( 1, sizeof( FIRM ) );
if ( !firm )
{
fprintf(stderr,
"ERROR in %s/%(): cannot allocate %s bytes of memory.\n",
__FILE__,
__FUNCTION__,
sizeof( FIRM ) );
exit( 1 );
}
firm->firm_name = firm_name;
firm->firm_zip_code = firm_zip_code;
return firm;
}
double firm_get_distance_miles_double( int firm_zip_code,
int residential_zip_code )
{
double miles_double;
miles_double = /* code to compute distance between two zip codes */
return miles_double;
}
/* main.c */
/* ------ */
#include "stdio.h"
#include "firm.h"
int main( int argc, char **argv )
{
FIRM *firm = firm_new_firm( "Acme Retailer", 33014 );
printf( "Got distance = %lf\n",
firm_get_distance_miles_double(
firm->firm_zip_code,
95825 ) );
return 0;
}
*Stephen R. Schach; "Software Engineering"; 1990; pp. 219-233.
*W. P. Stevens, G. J. Myers, and L. L. Constantine; "Structured Design, IBM Systems Journal, Vol. 13"; 1974; pp. 115-139.