SDSU CS 635 Advanced Object-Oriented Design & Programming
Spring Semester, 2001
Module Coupling & Cohesion
Previous    Lecture Notes Index    Next    
© 2001, All Rights Reserved, SDSU & Roger Whitney
San Diego State University -- This page last updated 06-Feb-01

Contents of Doc 2, Module Coupling & Cohesion



References

Object Coupling and Object Cohesion, chapter 7 of Essays on Object-Oriented Software Engineering , Vol. 1, Berard, Prentice-Hall, 1993


Doc 2, Module Coupling & Cohesion Slide # 2

Quality of Objects



Decomposing systems into smaller pieces aids software development

100 functions each 100 line of code long is "better" than
One function 10,000 lines of code long


Doc 2, Module Coupling & Cohesion Slide # 3
Parnas (72) KWIC (Simple key word in context) experiment

Parnas compared two different implementations

Write down in order list of high level tasks to be done
Each high level task becomes a module (function)

List
Difficult design decisions
Design decisions that are likely to change
Each module should hide a design decision


All ways of decomposing an application are not equal


Doc 2, Module Coupling & Cohesion Slide # 4
Parnas's Criteria

Primary goal of decomposition into modules is reduction of software cost

Specific goals of module decomposition

Each module's structure should be simple enough to understood fully







Doc 2, Module Coupling & Cohesion Slide # 5
Concepts for quality

Coupling

Strength of interaction between objects in system


Cohesion

Degree to which the tasks performed by a single module are functionally related


If some ways of decomposing a system into modules are better than others, how do we tell which are better. When we design/implement a system how can we tell how we are doing. Coupling and cohesion are two concepts that help us out. Understanding these ideas help us design better.


Doc 2, Module Coupling & Cohesion Slide # 6

Coupling



Decomposable system

One or more of the components of a system have no interactions or other interrelationships with any of the other components at the same level of abstraction within the system


A nearly decomposable system

Every component of the system has a direct or indirect interaction or other interrelationship with every other component at the same level of abstraction within the same system


Design Goal

The interaction or other interrelationship between any two components at the same level of abstraction within the system be as weak as possible


Doc 2, Module Coupling & Cohesion Slide # 7
Coupling

Measure of the interdependence among modules

"Unnecessary object coupling needlessly decreases the reusability of the coupled objects "

"Unnecessary object coupling also increases the chances of system corruption when changes are made to one or more of the coupled objects"


Types of Modular CouplingIn order of desirability

Data Coupling (weakest – most desirable)

Control Coupling

Global Data Coupling

Internal Data Coupling (strongest – least desirable)

Content Coupling (Unrated)

Doc 2, Module Coupling & Cohesion Slide # 8
Modular Coupling

Data Coupling



Output from one module is the input to another

Using parameter lists to pass items between routines


Common Object Occurrence:

Object A passes object X to object B
Object X and B are coupled
A change to X's interface may require a change to B

Example

class Receiver
   {
   public void message( MyType X )
      {
      // code goes here
      X.doSomethingForMe( Object data );
      // more code
      }
   }

Doc 2, Module Coupling & Cohesion Slide # 9
Modular CouplingData Coupling

Major Problem
Object A passes object X to object B
X is a compound object
Object B must extract component object Y out of X
B, X, internal representation of X, and Y are coupled



Doc 2, Module Coupling & Cohesion Slide # 10
Example: Sorting student records, by ID, by Name

How does the SortedList method add() add the new student record object and resort the list? To do this it needs to access the ID (name) fields of StudentRecord!

class StudentRecord {
   Name lastName;
   Name firstName;
   long ID;
   
   public Name getLastName() { return lastName; }
   // etc.
}
SortedList cs535 = new SortedList();
StudentRecord newStudent;
//etc.
cs535.add ( newStudent );


Doc 2, Module Coupling & Cohesion Slide # 11
Solution 1 Bad News

Here the add method actually accesses the StudentRecord method to get the ID. What is wrong with that? Why is this bad news?

class SortedList
   {
   Object[] sortedElements = new Object[ properSize ];
   public void add( StudentRecord X )
      {
      // coded not shown
      Name a = X.getLastName();
      Name b = sortedElements[ K ].getLastName();
      if ( a.lessThan( b ) )
         // do something
      else
         // do something else
      }
   }

Doc 2, Module Coupling & Cohesion Slide # 12
Solution 2  Send message to object to compare self to another StudentRecord Object

How is this any better that solution 1? Is it any better? How does it differ?

class SortedList{
   Object[] sortedElements = new Object[ properSize ];
   public void add( StudentRecord X ) {
      // coded not shown
      if ( X.lessthan( sortedElements[ K ] ) )
         // do something
      else
         // do something else
   }
}
class StudentRecord{
   private Name lastName;
   private long ID;
   public boolean lessThan( Object compareMe ) {
      return lastName.lessThan( compareMe.lastName );
   }
   etc.
}

Doc 2, Module Coupling & Cohesion Slide # 13
Solution 3  Interfaces or "required operations"
Notice how the SortedList is no longer coupled to the StudentRecord class. It can be used to sort any list of objects of the same class than implement Comparable.
interface Comparable {
   public boolean lessThan( Object compareMe ); 
   public boolean greaterThan( Object compareMe ); 
   public boolean equal( Object compareMe ); 
}
class StudentRecord implements Comparable {
   private Name lastName;
   private long ID;
   public boolean lessThan( Object compareMe ) {
      return lastName.lessThan( ((Name)compareMe).lastName );
   }
}
class SortedList {
   Object[] sortedElements = new Object[ properSize ];
   public void add( Comparable X ) {
      // coded not shown
      if ( X.lessthan( sortedElements[ K ] )
         // do something
      else
         // do something else
      }
   }

Doc 2, Module Coupling & Cohesion Slide # 14
Solution 4 Function Pointers
Code is neither legal C/C++ nor Java. The idea is to pass in a function pointer to the SortList object, which it uses to compare the objects in the list.

typedef int (*compareFun ) ( StudentRecord, StudentRecord );
class SortedList {
   StudentRecord[] sortedElements = 
         new StudentRecord[ properSize ];
    int (*compare ) ( StudentRecord, StudentRecord );
   public setCompare( compairFun newCompare )
      { compare = newCompare; }
   public void add( StudentRecord X ) {
      // coded not shown
      if ( compare( X,  sortedElements[ K ] ) )
      // code not shown
   }
}
int compareID( StudentRecord a, StudentRecord b )
   { // code not shown }
int compareName( StudentRecord a, StudentRecord b )
   { // code not shown }
SortedList myList = new SortedList();
myList.setCompair( compareID );

Doc 2, Module Coupling & Cohesion Slide # 15
Functor PatternFunctions as Objects

Functors are functions that behave like objects

They serve the role of a function, but can be created, passed as parameters, and manipulated like objects

A functor is a class with a single member function

Note 1: Functors violate the idea that a class is an abstraction with operations and state. Beginners should avoid using the Functor pattern, as they can lead to bad habits. The functor pattern is used here only as a last resort.

Note 2: The Command pattern is similar to the Functor pattern, but contains operations and state.

Note 3: For more information about patterns see: http://www.eli.sdsu.edu/courses/spring98/cs635/notes/patternIntro/patternIntro.html .For more information about Functor and Command pattern see: http://www.eli.sdsu.edu/courses/spring98/cs635/notes/command/command.html


Doc 2, Module Coupling & Cohesion Slide # 16
Function Pointers in JavaComparator in Java 2 (JDK 1.2)
In Java 2, the Comparator interface defines an interface for objects that act like functions pointers to compare objects.


Methods in Comparator Interface
int compare(Object o1, Object o2)
Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second
boolean equals(Object obj)
Indicates whether some other object is "equal to" this Comparator.

The implementer must ensure that:

sgn(compare(x, y)) == -sgn(compare(y, x)) for all x and y

compare(x, y) must throw an exception if and only if compare(y, x) throws an exception.)

((compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0.

x.equals(y) || (x==null && y==null) implies that compare(x, y)==0.

compare(x, y)==0 implies that sgn(compare(x, z))==sgn(compare(y, z)) for all z.

Doc 2, Module Coupling & Cohesion Slide # 17
Comparator Example

import java.util. Comparator;
class Student  {
   String name;
   int id;
   
   public Student( String newName, int id ) {
      name = newName;
      this.id = id;
      }
   
   public String toString() {
      return name + ":" + id;
      }
   }
final class StudentNameComparator implements Comparator {
   
   public int compare( Object leftOp, Object rightOp ) {
      String leftName = ((Student) leftOp).name;
      String rightName = ((Student) rightOp).name;
      return leftName.compareTo( rightName );
   }
   
   public boolean equals( Object comparator ) {
      return comparator instanceof StudentNameComparator;
   }
}

Doc 2, Module Coupling & Cohesion Slide # 18
//Comparator Example Continued

final class StudentIdComparator implements Comparator {
   static final int LESS_THAN = -1;
   static final int GREATER_THAN = 1;
   static final int EQUAL = 0;
   
   public int compare( Object leftOp, Object rightOp ) {
      long leftId = ((Student) leftOp).id;
      long rightId = ((Student) rightOp).id;
      if ( leftId < rightId )   
         return LESS_THAN;
      else if ( leftId > rightId )
         return GREATER_THAN;
      else
         return EQUAL;
   }
   
   public boolean equals( Object comparator ) {
      return comparator instanceof StudentIdComparator;
   }
}

Doc 2, Module Coupling & Cohesion Slide # 19
//Comparator Example Continued
import java.util.*;
public class Test  {
   public static void main(String args[])  {
      Student[] cs596 = { new Student( "Li", 1 ), new Student( "Swen", 2 ), 
                                 new Student( "Chan", 3 ) };
      //Sort the array
      Arrays.sort( cs596, new StudentNameComparator() );
      for ( int k = 0; k < cs596.length; k++ )
         System.out.print( cs596[k].toString() + ", " );
      System.out.println( );
      
      List cs596List = new ArrayList( );
      cs596List.add( new Student( "Li", 1 ) );
      cs596List.add( new Student( "Swen", 2 ) );
      cs596List.add( new Student( "Chan", 3 ) );
      System.out.println( "Unsorted list " + cs596List );
      //Sort the list
      Collections.sort( cs596List,  new StudentNameComparator() );
      System.out.println( "Sorted list " + cs596List );
      //TreeSets are aways sorted
      TreeSet cs596Set = new TreeSet(  new StudentNameComparator() );
      cs596Set.add( new Student( "Li", 1 ) );
      cs596Set.add( new Student( "Swen", 2 ) );
      cs596Set.add( new Student( "Chan", 3 ) );
      System.out.println( "Sorted Set " + cs596Set );
   }
}

Doc 2, Module Coupling & Cohesion Slide # 20
//Comparator Example ContinuedOutput
Chan:3, Li:1, Swen:2, 
Unsorted list [Li:1, Swen:2, Chan:3]
Sorted list [Chan:3, Li:1, Swen:2]
Sorted Set [Chan:3, Li:1, Swen:2]

Doc 2, Module Coupling & Cohesion Slide # 21
Sorting With Different Keys
import java.util.*;
public class MultipleSorts {
   public static void main(String args[]) {
      List cs596List = new ArrayList( );
      cs596List.add( new Student( "Li", 1 ) );
      cs596List.add( new Student( "Swen", 2 ) );
      cs596List.add( new Student( "Chan", 3 ) );
      
      Collections.sort( cs596List,  new StudentNameComparator() );
      System.out.println( "Name Sorted list " + cs596List );
      Collections.sort( cs596List,  new StudentIdComparator() );
      System.out.println( "Id Sorted list " + cs596List );
      TreeSet cs596Set = new TreeSet( new StudentNameComparator());
      cs596Set.addAll( cs596List );
      System.out.println( "Name Sorted Set " + cs596Set );
      TreeSet cs596IdSet = new TreeSet( new StudentIdComparator() );
      cs596IdSet.addAll( cs596List );
      System.out.println( "Id Sorted Set " + cs596IdSet );
   }
}
Output
Name Sorted list [Chan:1, Li:2, Swen:1]
Id Sorted list [Chan:1, Swen:1, Li:2]
Name Sorted Set [Chan:1, Li:2, Swen:1]
Id Sorted Set [Chan:1, Li:2]

Doc 2, Module Coupling & Cohesion Slide # 22
Solution 5 Function Pointers using generic types

typedef int (*compairFun ) ( <type>, <type> );

Doc 2, Module Coupling & Cohesion Slide # 23
Modular Coupling

Control Coupling


Passing control flags between modules so that one module controls the sequencing of the processing steps in another module

Common Object Occurrences:

A sends a message to B
B uses a parameter of the message to decide what to do

class Lamp {
   public static final ON = 0;
   public void setLamp( int setting ) {
      if ( setting == ON )
         //turn light on
      else if ( setting == 1 )
         // turn light off
      else if ( setting == 2 )
         // blink
   }
}
Lamp reading = new Lamp();
reading.setLamp( Lamp.ON );
reading.setLamp)( 2 );

Doc 2, Module Coupling & Cohesion Slide # 24
Cure:
Decompose the operation into multiple primitive operations

class Lamp {
   public void on() {//turn light on }
   public void off() {//turn light off }
   public void blink() {//blink }
}
Lamp reading = new Lamp();
reading.on();
reading.blink();


Doc 2, Module Coupling & Cohesion Slide # 25
Control Coupling

Common Object Occurrences:

A sends a message to B
B returns control information to A

Example: Returning error codes

class Test {
   public int printFile( File toPrint ) {
      if ( toPrint is corrupted )
         return CORRUPTFLAG;
      blah blah blah
   }
}
Test when = new Test();
int result =  when.printFile( popQuiz );
if ( result == CORRUPTFLAG )
   blah
else if ( result == -243 )

Doc 2, Module Coupling & Cohesion Slide # 26
Cure: Use exceptions

How does this reduce coupling?

class Test  {
   public int printFile( File toPrint ) throws PrintExeception {
      if ( toPrint is corrupted )
         throws new PrintExeception();
      blah blah blah
   }
}
try {
   Test when = new Test();
   when.printFile( popQuiz );
}
catch ( PrintException printError ) {
   do something
}

Doc 2, Module Coupling & Cohesion Slide # 27
Modular Coupling

Global Data Coupling


Two or more modules share the same global data structures

Common Object Occurrence :

A method in one object makes a specific reference to a specific external object

A method in one object makes a specific reference to a specific external object, and to one or more specific methods in the interface to that external object

A component of an object-oriented system has a public interface which consists of items whose values remain constant throughout execution, and whose underlying structures/implementations are hidden

A component of an object-oriented system has a public interface which consists of items whose values remain constant throughout execution, and whose underlying structures/implementations are not hidden

A component of an object-oriented system has a public interface which consists of items whose values do not remain constant throughout execution, and whose underlying structures/implementations are hidden

A component of an object-oriented system has a public interface which consists of items whose values do not remain constant throughout execution, and whose underlying structures/implementations are not hidden

Doc 2, Module Coupling & Cohesion Slide # 28

Internal Data Coupling


One module directly modifies local data of another module

Common Object Occurrence:

C++ Friends

A friend of a class in C++ has complete access to all private members of the class. This is a clear violation of the information hiding feature of the class. Since the class must list its friends, the violation is controlled. There are situations (defining the io operators <<, >>) where the use of friends can not be avoided


Doc 2, Module Coupling & Cohesion Slide # 29
Modular Coupling

Lexical Content Coupling


Some or all of the contents of one module are included in the contents of another

Common Object Occurrence :

C/C++ header files


Decrease coupling by:

Restrict what goes in header file
C++ header files should contain only class interface specifications


Doc 2, Module Coupling & Cohesion Slide # 30

Cohesion


"Cohesion is the degree to which the tasks performed by a single module are functionally related."

IEEE, 1983


"Cohesion is the "glue" that holds a module together. It can be thought of as the type of association among the component elements of a module. Generally, one wants the highest level of cohesion possible."

Bergland, 1981

"A software component is said to exhibit a high degree of cohesion if the elements in that unit exhibit a high degree of functional relatedness. This means that each element in the program unit should be essential for that unit to achieve its purpose."

Sommerville, 1989


Doc 2, Module Coupling & Cohesion Slide # 31
Types of Module CohesionFrom Worst to Best


Coincidental (worst)

Logical

Temporal

Procedural

Communication

Sequential

Functional (best)



Doc 2, Module Coupling & Cohesion Slide # 32
Module Cohesion

Coincidental


Little or no constructive relationship among the elements of the module

Common Object Occurrence:

Object does not represent any single object-oriented concept
Collection of commonly used source code as a class inherited via multiple inheritance


class Rous
   {
   public static int findPattern( String text, String pattern)
      { // blah}
   public static int average( Vector numbers )
      { // blah}
   public static OutputStream openFile( String fileName )
      { // blah}
      
   }


Doc 2, Module Coupling & Cohesion Slide # 33
Module Cohesion

Logical


Module performs a set of related functions, one of which is selected via function parameter when calling the module

Similar to control coupling

Cure:

Isolate each function into separate operations

public void sample( int flag )
   {
   switch ( flag )
      {
      case ON:
         // bunch of on stuff
         break;
      case OFF:
         // bunch of off stuff
         break;
      case CLOSE:
         // bunch of close stuff
         break;
      case COLOR:
         // bunch of color stuff
         break;
      }
   }


Doc 2, Module Coupling & Cohesion Slide # 34
Module Cohesion

Temporal


Elements are grouped into a module because they are all processed within the same limited time period

Common example:

"Initialization" modules that provide default values for objects

"End of Job" modules that clean up

procedure initializeData()
   {
   font = "times";
   windowSize = "200,400";
   foo.name = "Not Set";
   foo.size = 12;
   foo.location = "/usr/local/lib/java";
   }

Cure: Each object should have a constructor and destructor

class foo
   {
   public foo()
      {
      foo.name = "Not Set";
      foo.size = 12;
      foo.location = "/usr/local/lib/java";
      }
   }

Doc 2, Module Coupling & Cohesion Slide # 35
Sample Configuration File

[Macintosh]
[General]
EquationWindow=146,171,406,661
Zoom=200
SpacingWindow=0,0,0,0
CustomZoom=150

ShowAll=0

Version=2.01
[Spacing]
OptimalPrinter=1
LineSpacing=150%
MinRect=0
MatrixRowSpacing=150%
ForceOpen=0
MatrixColSpacing=100%
ToolbarDocked=1
SuperscriptHeight=45%
ToolbarShown=1
SubscriptDepth=25%
ToolbarDockPos=1
LimHeight=25%

LimDepth=100%
[Fonts]
LimLineSpacing=100%
Text=Times
NumerHeight=35%
Function=Times
DenomDepth=100%
Variable=Times,I
FractBarOver=1pt
LCGreek=Symbol,I
FractBarThick=0.5pt
UCGreek=Symbol
SubFractBarThick=0.25pt
Symbol=Symbol
FenceOver=1pt
Vector=Times,B
SpacingFactor=100%
Number=Times
MinGap=8%

RadicalGap=2pt
[Sizes]
EmbellGap=1.5pt
Full=12pt
PrimeHeight=45%
Script=7pt

ScriptScript=5pt

Symbol=18pt

SubSymbol=12pt


Call these constructors/destructors from a nonobject-oriented routine that performs a single, cohesive task



Doc 2, Module Coupling & Cohesion Slide # 36
Module Cohesion

Procedural


Associates processing elements on the basis of their procedural or algorithmic relationships


Procedural modules are application specific

In context the module seems reasonable

Removed from the context these modules seem strange and very hard to understand

Why is that being done here?

Can not understand module without understanding the program and the conditions existing when module is called

Makes module hard to modify, understand

Class Builder verse Program writer

Cure:

Redesign the system
If a module is necessary, remove it from objects



Doc 2, Module Coupling & Cohesion Slide # 37
Module Cohesion

Communication


Operations of a module all operate upon the same input data set and/or produce the same output data


Cure:

Isolate each element into separate modules


Rarely occurs in object-oriented systems due to polymorphism



Doc 2, Module Coupling & Cohesion Slide # 38
Module Cohesion

Sequential


Sequential association the type in which the output data from one processing element serve as input data for the next processing element

A module that performs multiple sequential functions where the sequential relationship among all of the functions is implied by the problems or application statement and where there is a data relationship among all of the functions


Cure:

Decompose into smaller modules



Doc 2, Module Coupling & Cohesion Slide # 39
Module Cohesion

Functional



If the operations of a module can be collectively described as a single specific function in a coherent way, the module has functional cohesion

If not, the module has lower type of cohesion



In an object-oriented system:





Doc 2, Module Coupling & Cohesion Slide # 40
Module Cohesion

Informational Strength


Myers states:

"The purpose of an informational-strength module is to hide some concept, data structure, or resource within a single module.

An informational-strength module has the following definition:





Copyright ©, All rights reserved.
2001 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
OpenContent license defines the copyright on this document.

Previous    visitors since 06-Feb-01    Next