Coupling

Types of Modular Coupling

In order of desirability

  • Data Coupling (weakest ­ most desirable)
  • Control Coupling
  • Global Data Coupling
  • Internal Data Coupling (strongest ­ least desirable)
  • Content Coupling (Unrated)

Data Coupling

Output from one module is the input to another

Using parameter lists to pass items between routines

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

 

class Receiver {

   public void message( MyType X ) {

          // code goes here      

         X.doSomethingForMe( Object data );

         // more code

    }

}

 

Control Coupling

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

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 );

Problem: A needs to know the messages it can pass to B.

A Solution:

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();

 

Global Data Coupling

Two or more modules share the same global data structures

Example

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

Internal Data Coupling

One module directly modifies local data of another module

Example: C++ Friends

Lexical Content Coupling

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

Example: C/C++ header files

Solution: Restrict what goes in header file

Decoupling a Design

Problem: both Kitchen and Cash Register use Food class...too coupled to very different useages.

 

Solution:

  • declare Interfaces that are used by Kitchen and Cash Register instead of an explicit class Food.

  • Food implements those Interfaces

  • To get the true benefits of polymorphism - or 'pluggability' - in a program, it is important to declare variables and parameters not with explicit classes, but via an interface (abstract class in C++, interface in Java, deferred class in Eiffel).
  • Food is used by both Kitchen and Cash Register. But these clients need different behaviour from Food, so we separate their requirements into different interfaces: Edible for the kitchen's requirements of food, and Saleable for the till's. By doing this, we have made the design more flexible - and the business too: because now we can consider edible things that are not saleable (ingredients such as flour), and saleable things that are not edible - we could start selling newspapers in our café. Our original Food class happens to implement both interfaces. Some good programmers insist that we should always use interfaces to declare variables and parameters. Simple multiple inheritance of rôle-types can be considered a pattern for composing collaborations.

 

 

© Lynne Grewe