A module is a relatively small unit of a system that is defined by its function. Modules are self-contained system components. As much, all of the computer instructions contained in a module should contribute to the same function. Modules are executed as units and, in most instances, have a single point of entry and a single point of exit. Standard programming terms used to identify modules include COBOL sections, paragraphs, or subprograms, and subroutines in BASIC or FORTRAN. For object-oriented programming languages, a module would roughly be a method. A computer program is typically made up of several modules. Modules may also represent separately compiled programs, subprograms, or identifiable internal procedures.
Modules are collection of data and operations on data. It supports the object-oriented concepts of abstraction and encapsulation. Modules does not support object-oriented programming since it does not support inheritance. This limited kind of object-oriented is called object-based programming.
Here are some good areas in which to create modules:
The extent to which all instructions in a module relate to a single function is called cohesion. In a truly cohesive module, all of the instructions in the module pertain to performing a single, unified task. Maximally cohesive modules also tend to be the most loosely coupled, so achieving high levels of cohesion in system design thus helps to minimize coupling. If a module is designed to perform one and only one function, then it has no need to know about the interior workings of other modules. The cohesive module only needs to take the data it is passed, act on them, and pass its output on its super- ordinate module.
"The degree of interaction within a module--the glue that holds a module together." From Best to worst Functional Cohesion. Modules perform exactly one action or achieve a single goal. Informational Cohesion. Modules perform a number of actions, each with its own entry point, with independent code for each action, all performed on the same data structure. Communicational Cohesion. Modules perform a series of actions related by the sequence of steps to be followed, & also, all the actions are performed on the same data. Procedural Cohesion. Modules perform a series of actions related by the sequence of steps to be followed by the product. Temporal Cohesion. Modules perform a series of actions related by time. Logical Cohesion. Modules perform a series of related actions, one of which is selected by the calling module. Coincidental Cohesion. Modules perform multiple unrelated actions, or actions cannot be defined (i.e., must be described in terms of logic rather than action).
Information Hiding and Modules
Modules are characterized by design decisions that are hidden from others
Modules communicate only through well defined interfaces
Enforce access constraints to local entities and those visible through interfaces
Very important for accommodating change and reducing coupling
Coupling is one of the two main criterias of module design.
The degree of interaction between modules--the wiring connecting the modules. Coupling describes the interconnection among modules.
From best to worst:
Data coupling
Two modules are data coupled if they communicate by passing parameters. That is, all
parameters are homogeneous data types. Occurs when one module passes local data values to
another as parameters.
Stamp coupling
Two modules are stamp coupled if they communicate via a passed data structure that
contains more information than necessary for them to perform their functions. That is,
parameters include complex data structures, but modules operate on only some of the
pieces. Occurs when part of a data structure is passed to another module as a parameter.
Control Coupling
Two modules are control coupled if they communicate using at least one "control
flag". That is, control element passed to a module ( one module explicitly controls
the logic of the other ) Occurs when control parameters are passed between modules.
Common Coupling
Two modules are common coupled if they both share the same global data area. Another
design principle you have been taught since day one: don't use global data. That is,
multiple modules have access to the same global data. Occurs when multiple modules access
common data areas such as Fortran Common or C /C++ extern.
Content Coupling
Two modules are content coupled if:
one module changes a statement in another (Lisp was famous for this ability)
one module references or alters data contained inside another module
one module branches into another module
That is, one module directly references the contents of the other. Occurs when a module
data in another module.
Subclass Coupling
This is the case that encapsulation breaks by inheritance. The coupling that a class has
with its parent class.
1. A module should provide a comprehensive set of services so that the rest of the program can interact with it cleanly. That is, data and operations on the data are reasonably and effectively wrapped in one place.
2. Module data should be locally global . It is like global data in that more than one routine can access it only if the routines are in the same module of the data. Unlike global data, its not accessible to the rest routines outside the module in a program.
3. Data into/out of a module should be passed via parameters, and only via external visible routines.
4. Module should hide as much of their internal data as possible.No data that used by routines in a module should be externally visible. Module should hide implementation details that are designed for internal use as well.
5. Sometimes, status values are made externally visible, so long as the module does not use them. In C, we use a static with a source file. Items declared by static at global level can only be seen within this source file. C++ and Java allow private declarations, also allow protected declaration.
6. Evaluate times and again to reduce coupling and improve cohesion. Package the module based on design constraints and portability requirements.
7. Define modules with predictable function & avoid being overly restrictive. Avoid static memory between calls where possible.Keep scope of effect of a module within scope of control of that module
Accommodating changes is one of the most challenging aspects of good program design. The goal is to isolate unstable areas so that the effect of a change will be limited to one module. Here are a few areas that are likely to change:
Hardware dependencies Be aware of posiible changes arisng from using different hardwares. For example, the changes in dementions, solution, colors, available fonts etc. for screens, printers and plotters. Other hardware dependencies include interface with disk, communication ports, sound and graphic facilities etc. Input and output Input/output is a volatile area. If your application creates its own data files, the format will probably change as your application becomes more sophisticetd. So, it's a good idea to examine all external interfaces for possible changes. Language extentions If you use nonstandard extentions to your programming language, put the extentions in a module of their own to be ready to accommodate different enviroment. The difficult design and implementation areas The more difficult and complicated the design and implementation areas are, the more likely and poorly they might be done. Changes to these areas are almost definite consideration. Status variables Status variable indicate the state of a program and tend to be changed more frequently than most other data. Don't use a boolean variable as a status variable. Use access routines instead of checking the status variable directly. Data-size constraints Named constants are always the first choice to prevent data-size from being a literally exposed to the outside. Business rules business rules are the laws, regulations, policies and procedures that you enciding into a computer system. There are some other areas prone to changes, such as: Complex data Complex logic Operations at the programming-language level All other potential changes you could anticipate
1. Identify items that seem likely to change. .
"If the requirements have been done well, they include a list of potential changes and the likelihood of each change. In such a case, identifying the likely changes is easy. If the requirements don't cover potential changes, see the discussion that follows of areas that are likely to change in any project.".
2. Separate items that are likely to change..
"Compartmentalize eah volatile component identified in step 1 into its own module, or into a module with other volatile components that are likely to change at the same time.".
3. Isolate items that seem likely to change. .
"Design the intermodule interfaces to be insensitve to the potential changes. Design the interfaces so that changes are imited to the inside of the module and the outside remains unaffected. Any other module using the changes module should be unaware that the change has occurred. The modules's interface should protect its secrets.".
The example modules illustrated are all having good characteristics of module and showing Object-Oriented design style (To maintain a clear scene, most comments are cut): Each module has a central purpose, Data and operations are well organized in each module The module offers cohesive set of services Each module is independent of another, and loosely coupled Each module has no access to meddle with the internal data of others' Each module embodies abstraction, information hiding Go directly to each program:
To use modules in languages that don't support modularity, use programming standards as a subsititute for direct language support.
char Name[32]; #define NAME_SIZE 32 //if we have a size limit, do it this way ... char Name[NAME.SIZE+1] for (i=0; i=NAME.SIZE; i++)
Function A calls Function B, Function B calls Function C, Function C calls Function A.
1) #define a Marco 2) define "inline" functions
A high-quality module should have a strong cohesion and a loose coupling. Here is an example of a low-quality module in Java. You should be able to find many different problems with this module: The module has a bad name. Distance is an ambiguous name. It only tells you its a module about distance, but it is not what the module actually does. Internal data kilo in the module is declared as a public data. It is visible everywhere. Variable mile is entered by user. It should pass via parameter.
Routine mileToKilo() is public. The implementation details do not hidden. Here is a module for a same operation. The module is better than the first because it has a much-improved cohesion and loose coupling. Click here . It has a more meaningful name. All the data are not visible outside of the module. You can only access the data via internal routines. Variable passes via parameter and there is not interface with user. The implementation details were hidden by hiding internal routine mileToKilo().
Reference:
Code Complete, A Practical Handbook of Software Construction.
Steve McConnell. Microsoft Press (1993).
Original Authors :Brien Beattie, Dean Varg, Yixiang Wang, Yawen Wu, Hong
Zhang
Date : June 4, 2000
Modififed By :Sirigon Sukpan, Hua Ma, Cyren Aldecoa, Gerald Barrie, Curtis
Ferchoff,Quanxiang Li
Date : June 8, 2000
Copyright 2000 Department of Computer Science, University of
Regina.