Software Engineering I
Introduction to Modules
& Objects
To understand the concept of an object we must first be clear about the concept of a module. The desirable features for a module overlap with the formulation of objects.
A module is defined as
“A set of one or more contiguous program statements having a name by which other parts of the system can invoke it, and preferably having its own distinct set of variable names. ” – Stevens, Myers & Constantine
To rate a module we examine two factors: -
Coupling - This is the degree of interaction between modules; i.e. their inter-relationships
Cohesion – This is the degree of interaction between statements in a module.
* Good modules exhibit low coupling but high cohesion
We will address these two factors as follows,
There are several types of cohesion. We rank them going from the worst form of cohesion to the best
· Coincidental (bad)
·
![]()
Logical
· Temporal
· Procedural
· Communicational
· Informational
· Functional (good)
Note. This scale is a relative one; a module may contain some or all of these types to one extent or another.
Coincidental Cohesion: This is the worst form of cohesion. This is where a module performs multiple unrelated tasks. This may occur if modules are not properly designed.
Logical Cohesion: Here modules can perform a series of related tasks, however only one is selected by the calling module.
Temporal Cohesion: The module performs a series of actions that are related in time. E.g. all startup/shutdown activities are brought together.
Procedural Cohesion: Here elements in a module perform a sequence of steps to be followed by the product. The elements in the module thus make up a single control sequence and must be executed in specific order.
Communicational Cohesion: All elements operate on the same input data set or produce the same output data set.
Informational (Sequential) Cohesion: Output from one element in the module serves as input for some other element. Unlike logical cohesion the code for each action is completely independent. A module with informational cohesion is essentially an ADT (abstract data type) and all the benefits of using an ADT are gained when this type of cohesion is employed in a module. Such a module operates on the same data structure. Objects (when well designed) are modules that exhibit informational cohesion.
Functional Cohesion: Module contains elements that perform exactly one function or achieves a single goal.
There are also several kinds of coupling, which we rate as follows -:
· Content (bad)
· Common
· Control
· Stamp
· Data (good)
Content Coupling: This occurs when one module directly references the contents of another module. E.g. module x branches to a local label in module y or module x modifies a statement of module y. Such modules are inextricably linked to each other.
- Content coupling is quite dangerous.
Common Coupling: This occurs when several modules have
access to the same global data. E.g. use of the C++ modifier public
- Common coupling contradicts the structured programming concept and is quite undesirable
Control Coupling: This occurs when one module has control over the logic of another. If module x calls module y and y determines what action x must take then control coupling is present. The passing of a control switch statement as an argument is an example of control coupling.
Stamp Coupling: This is the case where entire data structures are passed to the called module but only some individual fields are used. E.g. pointer passing in C. Note. Not all the elements in the data structure are acted upon by the called module.
Data Coupling: Two modules are data coupled if all arguments are homogeneous data items. If a data structure is passed then the called module must use all the fields. Data coupling is a desirable goal. Modules which are data coupled are easier to maintain since changes in one is less likely to cause a regression fault in the other.
The following terms are important when considering modules and objects.
Encapsulation – gathering together into one unit all aspects of the real world entity modeled by that unit
Abstract Data Type – Entity that combines a data type with actions performed on instances of that type
Information Hiding – Designing a module in such a way that the implementation details are hidden from other modules
Class – An abstract data type that supports inheritance e.g. a rocking chair may be a class, derived from the class chair, which in turn may be derived from the class furniture
Object – An instance of a class e.g. your grandma’s rocking chair would be an instance of a class or (put another way) an object of the rocking chair class
Method – This is the name given to any function that belongs to a particular class.
Note. Terms class and object sometimes used interchangeably in certain texts
An object may be thought of as a module exhibiting informational (sequential) cohesion but also having other properties as well.
Objects support data hiding and encapsulation but have an extended characteristic called inheritance. The basic idea of inheritance is that newly defined data types can be made as extensions of existing ones, rather than having to be defined from scratch.
Objects attempt to model the real world so let us consider an example from the real world. For example, a passenger car is an object. More abstractly we could say that a passenger car is a motor vehicle. We might also say that a motor vehicle is a vehicle. This “is a “ relationship is known as inheritance.
We can place the information in a diagram by drawing the inheritance hierarchy:

We say that Vehicle is the parent (or base) class. Boat would be an example of a child class (with respect to Vehicle) and also a parent (with respect to Sail Boat). Note that a Sail boat ISA Boat and a Boat ISA Vehicle.
Consider the C++ code segment below
class HumanBeing
{
private:
int age;
float
height;
float
weight;
enum
{male,female} gender;
public: // find
here the declaration of operations on human beings
}; // class HumanBeing
class Parent:public HumanBeing // Parent inherits from
HumanBeing
{
private:
char
nameoffirstborn[30];
int
numberofchildren;
public:
// find
here the declaration of operations on Parent
}; // class Parent
Class Parent inherits all the attributes of the HumanBeing Class because Parent is derived from HumanBeing. If Ted is an instance of class Parent (i.e. an object) then Ted has all the attributes of a Parent, but also inherits all the attributes of a human being. In other words Ted the Parent ISA HumanBeing.
· We may say a Parent is a specialization of a HumanBeing, or a HumanBeing is a generalization of a Parent.

This is another key feature of Object Oriented programming. The word polymorphism means many (“Poly”) forms (“morph---“).
Consider the following –
A base class called FileManager is created which allows files to be added, deleted, updated etc. on a computer system.
Later three derived classes are added (i.e. they inherit properties of the base class)
See Diagram below…

Suppose we need to implement an open() method (i.e. a function to handle file opening in the class) we have a number of options including the 3 following major ones: -
1) Implement an open() method for each class giving 4 distinct open() methods …
2) Implement an open() method for the base class only and allow the three derived classes to inherit it from the base.
3) Make the open() function polymorphic
Option 1: To pursue this option would mean ignoring the power of inheritance. The open() methods in this case would all be tied to a particular object when the program is compiled. There might also be a difficulty in providing an open() for the FileManager (ancestor/parent object) since this would represent a generic (i.e. abstract) open().
Option 2: This option is more attractive than the first one except that three distinct types of storage media may require different actions to be carried out. E.g. a tape needs to be wound forwards/backwards while a disk must be spun etc.
Option 3: To use polymorphism in C++ a dummy open() method would be declared in the base class (.. this method specified as virtual in C++) . For each of the derived classes a distinct corresponding open() would be provided, each with its own unique code.
Now suppose we declare an object called Filer of type FileManager. When Filer.open() is run the system at that point in time will determine dynamically (this is called dynamic binding) which of the three open() methods (for Disk, CD-R or Tape) to run.
This strategy works because a derived class object “IS A” base class object. Note. The open() in FileManager is only a placeholder (and cannot actually run) due to the present of the keyword virtual.
Due to the open() method being applied to objects (i.e. instances) of different classes we say it is polymorphic or exhibits polymorphism. (Note. In C++ all virtual methods in a base class must be redefined in the derived class. The compiler will enforce this constraint.)
Caveat: Polymorphism/dynamic binding may cause a negative impact on maintenance. Determining which method (..in the case where many derived classes of the same base class are in existence.) was invoked can be a time consuming process.