CSC/ECE 517 Fall 2007/wiki2 7 as: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
(5)
m (5)
Line 54: Line 54:
== Types of coupling ==
== Types of coupling ==


=== DATA COUPLING ===
=== STAMP COUPLING ===
 
==== Definition of Stamp Coupling ====


==== Definition of Data Coupling ====
Stamp coupling occurs between modules when data are passed by parameters using a data structure containing fields which may or may not be used.


Data coupling occurs between two modules when data are passed by parameters using a simple argument list and every item in the list is used.  
*As a rule of thumb, never pass a data structure containing many fields to a module that only needs a few.
*Normally we dont make a distinction between the passing of parameters in an unstructured format (as described under data coupling) and the passing of parameters in a data structure (stamp coupling).  The distinction between data and stamp coupling is not relevant in object-oriented systems.
*;Strengths of Stamp Coupling
**It is a loose form of coupling.
**It simplifies interfaces between modules.
*;Weaknesses of Stamp Coupling
**It forces the creation of artificial data structures (i.e., bundling of unrelated data elements together in a structure). Data structures are appropriate as long as the data bundled together is meaningful and related.


*Use data coupling when the argument list is small.  As a rule of thumb, limit the argument list to three items.
==== Example ====
*;Strengths of Data Coupling
**A module sees only the data elements it requires.
**It is the best form of coupling.
*;Weakness of Data Coupling
**A module can be difficult to maintain if many data elements are passed.  Too many parameters can also indicate that a module has been poorly partitioned.


==== Example ====
In this example, we are passing an entire RECTANGLE to each of the functions, even though the function really doesn't need to see or modify all of the members.  Written this way, the function must know the names of the members and is also allowed to change any of the members.  Each of these functions really should have been written to take primitive types, not the entire RECTANGLE.


<pre>
<pre>
typedef struct rectangle
typedef struct rectangle
{
{
   int length;
   int length;
   int width;  
   int width;  
Line 81: Line 84:
} RECTANGLE;
} RECTANGLE;


int    CalcArea      (int width, int length);
RECTANGLE CalcArea      (RECTANGLE r);
int    CalcPerimeter (int width, int length);
RECTANGLE CalcPerimeter (RECTANGLE r);
double CalcDiagonal  (int width, int length);
RECTANGLE CalcDiagonal  (RECTANGLE r);


int main()
int main()
{
{
   RECTANGLE rect1;
   RECTANGLE rect1;
 
   
   rect1.length = 7;
   rect1.length = 7;
   rect1.width  = 6;
   rect1.width  = 6;
   rect1.color = RED;
   rect1.color   = RED;
   rect1.symbol = '#';
   rect1.symbol = '#';


   rect1.area = CalcArea(rect1.width, rect1.length);
   rect1 = CalcArea (rect1);
   rect1.perimeter = CalcPerimeter(rect1.width, rect1.length);
   rect1 = CalcPerimeter (rect1);
   rect1.diagonal = CalcDiagonal(rect1.width, rect1.length);
   rect1 = CalcDiagonal (rect1);


   printf("For width: %d and length %d\n",
   printf("For width: %d and length %d\n",
Line 107: Line 110:
}
}


int CalcArea (int width, int length)
RECTANGLE CalcArea (RECTANGLE r)
{
{
   int area;
   r.area = r.width * r.length;


  area = width * length;
   return r;
 
   return area;
}
}




int CalcPerimeter (int width, int length)
RECTANGLE CalcPerimeter (RECTANGLE r)
{
{
   int perimeter;
   r.perimeter = 2 * r.width + 2 * r.length;


  perimeter = 2 * width + 2 * length;
   return r;
 
   return perimeter;
}
}




double CalcDiagonal (int width, int length)
RECTANGLE CalcDiagonal (RECTANGLE r)
{
{
   double diagonal;
   r.diagonal = sqrt (r.width * r.width
                      + r.length * r.length);


  diagonal = sqrt (width * width
   return r;
                    + length * length);
 
   return diagonal;
}
}
</pre>
</pre>




=== STAMP COUPLING ===
=== DATA COUPLING ===
 
==== Definition of Data Coupling ====


==== Definition of Stamp Coupling ====
Data coupling occurs between two modules when data are passed by parameters using a simple argument list and every item in the list is used.


Stamp coupling occurs between modules when data are passed by parameters using a data structure containing fields which may or may not be used.  
*Use data coupling when the argument list is small.  As a rule of thumb, limit the argument list to three items.
*;Strengths of Data Coupling
**A module sees only the data elements it requires.
**It is the best form of coupling.
*;Weakness of Data Coupling
**A module can be difficult to maintain if many data elements are passed.  Too many parameters can also indicate that a module has been poorly partitioned.


*As a rule of thumb, never pass a data structure containing many fields to a module that only needs a few.
==== Example ====
*Normally we dont make a distinction between the passing of parameters in an unstructured format (as described under data coupling) and the passing of parameters in a data structure (stamp coupling).  The distinction between data and stamp coupling is not relevant in object-oriented systems.
*;Strengths of Stamp Coupling
**It is a loose form of coupling.
**It simplifies interfaces between modules.
*;Weaknesses of Stamp Coupling
**It forces the creation of artificial data structures (i.e., bundling of unrelated data elements together in a structure). Data structures are appropriate as long as the data bundled together is meaningful and related.


==== Example ====
This example shows a better way to write the previous program.  Here we will be passing and returning only primitive data types.  They are all that is really needed by the functions and now the functions are more general, too.


<pre>
<pre>
typedef struct rectangle
typedef struct rectangle
{
{
   int length;
   int length;
   int width;  
   int width;  
Line 167: Line 165:
} RECTANGLE;
} RECTANGLE;


RECTANGLE CalcArea      (RECTANGLE r);
int    CalcArea      (int width, int length);
RECTANGLE CalcPerimeter (RECTANGLE r);
int    CalcPerimeter (int width, int length);
RECTANGLE CalcDiagonal  (RECTANGLE r);
double CalcDiagonal  (int width, int length);


int main()
int main()
{
{
   RECTANGLE rect1;
   RECTANGLE rect1;
   
 
   rect1.length = 7;
   rect1.length = 7;
   rect1.width  = 6;
   rect1.width  = 6;
   rect1.color   = RED;
   rect1.color = RED;
   rect1.symbol = '#';
   rect1.symbol = '#';


   rect1 = CalcArea (rect1);
   rect1.area = CalcArea(rect1.width, rect1.length);
   rect1 = CalcPerimeter (rect1);
   rect1.perimeter = CalcPerimeter(rect1.width, rect1.length);
   rect1 = CalcDiagonal (rect1);
   rect1.diagonal = CalcDiagonal(rect1.width, rect1.length);


   printf("For width: %d and length %d\n",
   printf("For width: %d and length %d\n",
Line 193: Line 191:
}
}


RECTANGLE CalcArea (RECTANGLE r)
int CalcArea (int width, int length)
{
{
   r.area = r.width * r.length;
   int area;
 
  area = width * length;


   return r;
   return area;
}
}




RECTANGLE CalcPerimeter (RECTANGLE r)
int CalcPerimeter (int width, int length)
{
{
   r.perimeter = 2 * r.width + 2 * r.length;
   int perimeter;
 
  perimeter = 2 * width + 2 * length;


   return r;
   return perimeter;
}
}




RECTANGLE CalcDiagonal (RECTANGLE r)
double CalcDiagonal (int width, int length)
{
{
   r.diagonal = sqrt (r.width * r.width
   double diagonal;
                      + r.length * r.length);
 
  diagonal = sqrt (width * width
                    + length * length);


   return r;
   return diagonal;
}
}
</pre>
</pre>


=== CONTROL COUPLING ===
=== CONTROL COUPLING ===

Revision as of 03:16, 24 October 2007

Topic

Cohesion and coupling Cohesion and coupling are concepts that are reasonably easy to understand, but nonetheless, it is challenging to find good examples that are succinct. Browse the hundreds of Web pages that attempt to explain these concepts, picking your favorite examples. Many of these pages mention related concepts; list some of them and explain how they relate to cohesion and coupling. Be sure to mention the metrics that can be used to measure how well a program conforms to the principles of high cohesion and low coupling.

Definition

Coupling

Coupling is simply defined as the degree of interdependence between modules or its like a measure of the strength of interconnection of modules or objects.

  • The more the connections between one module and the rest, the harder to understand that module, the harder to re-use that module in another situation, the harder it is to isolate failures caused by faults in the module.
  • The lower the coupling the “better”.

Cohesion

Cohesion can be described as the extent to which its individual components are needed to perform the same task i.e. how tightly bound or related [a module’s] internal elements are to one another.

  • The less tightly bound the internal elements, the more disparate the parts to the module, the harder it is to understand.
  • The higher the cohesion the “better”.
Note
Low coupling is usually results in high degree of cohesion.
Some Small Definitions

Module a lexically contiguous sequence of program statements bounded by boundary elements, having an aggregate identifier.

Relationship A relationship exists between one module and another if that module cannot function correctly without the presence of the other.

Low Coupling and High Cohesion with different methods

Assuming the state of an object is the snapshot of its attributes in the time, all methods can belong to one of these three categories:

  • Utility: doesn't use or modify object state for ex: Integer.toString(int), Math.cos(double)
  • State View: use object state for ex: TextField.getText(), Object.toString()
  • State Change: modify object state for ex: Vector.addElement(..), Hashtable.clear()


An utility method can reach the lowest possible coupling:

  • takes only input parameters, and only if it needs them to make the output
  • returns a value (primitive or handle), or alters objects passed a parameters, and it produces all its output data (it doesn't call other methods)

A State/View method with lowest possible coupling does:

  • takes input parameters and uses attributes or methods (class or instance ones) belonging to its class (i.e. in every way but not from class members of others classes, constants excluded)
  • returns a value, alters parameters or throws an exception

A State/Change method with lowest possible coupling does:

  • takes input parameters and uses attributes or methods (class or instance ones) belonging to its class (i.e. in every way but not from class members of others classes, constants excluded)
  • returns a value, alters parameters or throws an exception , or through attributes and methods (class or instance ones) belonging to its class (i.e. in every way but not with class members of others classes)


To get high cohesion, the following are some simple thumb rules

  • The method must do only a single conceptual task. Ex: Instance methods, Constructors, wrappers, getter/setter methods.
  • A method must not assume the type/values of its parameters and arguments.

Types of coupling

STAMP COUPLING

Definition of Stamp Coupling

Stamp coupling occurs between modules when data are passed by parameters using a data structure containing fields which may or may not be used.

  • As a rule of thumb, never pass a data structure containing many fields to a module that only needs a few.
  • Normally we dont make a distinction between the passing of parameters in an unstructured format (as described under data coupling) and the passing of parameters in a data structure (stamp coupling). The distinction between data and stamp coupling is not relevant in object-oriented systems.
    Strengths of Stamp Coupling
    • It is a loose form of coupling.
    • It simplifies interfaces between modules.
    Weaknesses of Stamp Coupling
    • It forces the creation of artificial data structures (i.e., bundling of unrelated data elements together in a structure). Data structures are appropriate as long as the data bundled together is meaningful and related.

Example

In this example, we are passing an entire RECTANGLE to each of the functions, even though the function really doesn't need to see or modify all of the members. Written this way, the function must know the names of the members and is also allowed to change any of the members. Each of these functions really should have been written to take primitive types, not the entire RECTANGLE.

typedef struct rectangle
{	
   int length;
   int width; 
   int area;
   int perimeter;
   int color;
   double diagonal;
   char symbol;
} RECTANGLE;

RECTANGLE CalcArea      (RECTANGLE r);
RECTANGLE CalcPerimeter (RECTANGLE r);
RECTANGLE CalcDiagonal  (RECTANGLE r);

int main()
{
   RECTANGLE rect1;
    
   rect1.length = 7;
   rect1.width  = 6;
   rect1.color   = RED;
   rect1.symbol = '#';

   rect1 = CalcArea (rect1);
   rect1 = CalcPerimeter (rect1);
   rect1 = CalcDiagonal (rect1);

   printf("For width: %d and length %d\n",
          rect1.width, rect1.length);
   printf("The area, perimeter and diagonal are\n");
   printf("%d %d %f\n", rect1.area, rect1.perimeter,
          rect1.diagonal);

   return 0;
}

RECTANGLE CalcArea (RECTANGLE r)
{
   r.area = r.width * r.length;

   return r;
}


RECTANGLE CalcPerimeter (RECTANGLE r)
{
   r.perimeter = 2 * r.width + 2 * r.length;

   return r;
}


RECTANGLE CalcDiagonal (RECTANGLE r)
{
   r.diagonal = sqrt (r.width * r.width
                      + r.length * r.length);

   return r;
}


DATA COUPLING

Definition of Data Coupling

Data coupling occurs between two modules when data are passed by parameters using a simple argument list and every item in the list is used.

  • Use data coupling when the argument list is small. As a rule of thumb, limit the argument list to three items.
    Strengths of Data Coupling
    • A module sees only the data elements it requires.
    • It is the best form of coupling.
    Weakness of Data Coupling
    • A module can be difficult to maintain if many data elements are passed. Too many parameters can also indicate that a module has been poorly partitioned.

Example

This example shows a better way to write the previous program. Here we will be passing and returning only primitive data types. They are all that is really needed by the functions and now the functions are more general, too.

typedef struct rectangle
{
   int length;
   int width; 
   int area;
   int perimeter;
   int color;
   double diagonal;
   char symbol;
} RECTANGLE;

int    CalcArea      (int width, int length);
int    CalcPerimeter (int width, int length);
double CalcDiagonal  (int width, int length);

int main()
{
   RECTANGLE rect1;

   rect1.length = 7;
   rect1.width  = 6;
   rect1.color  = RED;
   rect1.symbol = '#';

   rect1.area = CalcArea(rect1.width, rect1.length);
   rect1.perimeter = CalcPerimeter(rect1.width, rect1.length);
   rect1.diagonal = CalcDiagonal(rect1.width, rect1.length);

   printf("For width: %d and length %d\n",
          rect1.width, rect1.length);
   printf("The area, perimeter and diagonal are\n");
   printf("%d %d %f\n", rect1.area, rect1.perimeter,
          rect1.diagonal);

   return 0;
}

int CalcArea (int width, int length)
{
   int area;

   area = width * length;

   return area;
}


int CalcPerimeter (int width, int length)
{
   int perimeter;

   perimeter = 2 * width + 2 * length;

   return perimeter;
}


double CalcDiagonal (int width, int length)
{
   double diagonal;

   diagonal = sqrt (width * width
                    + length * length);

   return diagonal;
}


CONTROL COUPLING

Definition of Control Coupling

Control coupling occurs between modules when data are passed that influence the internal logic of a module (e.g., flags and switches).

  • As a rule of thumb, use descriptive flags (i.e., a flag that describes a situation or condition, such as end-of-file). Do not use control flags.
    Object-Oriented Considerations
    • In object-oriented systems, control coupling occurs when an object receives a message from another object and the receiving object responds to the message differently based on control information contained in the message. Another type of control coupling is evident when a method returns control information to an object in responding to a message.
    • An example of object-oriented control coupling is a method that returns an error code with a value of zero when no errors are encountered handling a message.
  • It only a moderate form of coupling and doesnt affect the quality of the program that much.
  • Weaknesses of Control Coupling
    • Control flags passed down the hierarchy require the calling program to know about the internals of the called program (i.e., the called program is not a black box).
    • Control flags passed up the hierarchy cause a subordinate module to influence the flow of control in the parent module (i.e., the subordinate module has an affect on a module it does not control).

Example

void PrintBoard (char board[ROWS][COLS], int rows, int cols, int done) { 
  int i, j; 
  printf(" 0 1 2 3 4 5 6 7 8 9\n"); 
  printf(" -----------------------------------------\n"); 
  for(i = 0; i < rows; i++) { 
    printf("%d ", i); 
    for(j = 0; j < cols; j++) { 
      if(done) { 
        printf("| %c ", board[i][j]); 
      } else { 
        if(board[i][j] == ' ' || board[i][j] == 'O' || board[i][j] == 'X') { 
           printf("| %c ", board[i][j]); 
           } else { 
             printf("| "); 
           } 
      } 
    } 
    printf("|\n"); 
    printf(" -----------------------------------------\n"); 
  } 
} 

COMMON COUPLING

Definition of Common Coupling

Common coupling occurs when modules communicate using global data areas (i.e., universal common data areas). For example, C allows the developer to declare a data element as external, enabling it to be accessed by all modules.

  • Common coupling is also known as global coupling.
    Object-Oriented Considerations
    • In object-oriented systems, common coupling occurs when an object references a specific external object and has knowledge of the structure and implementation details of the external object. Generally one should avoid the use of data in the public interface of an object. However, it is sometimes necessary for objects to include items other than methods in their public interfaces. In these instances, the general guideline is to use constants rather than variables.
  • Weaknesses of Common Coupling
    • Modules are very tightly coupled. A fault in one module using global data may show up in another module because global data may be updated by any module at any time.
    • Modules referencing global data are tied to specific data names, unlike modules that reference data through parameters. This greatly limits the module's re-usability.
    • It may take considerable time for a maintenance programmer to determine what module updated the global data. The more global data used, the more difficult the job becomes to determine how modules obtain their data.
    • It is more difficult to track the modules that access global data when a piece of global data is changed (e.g., a field size is changed).

Example

int Function1 (int a) { 
  if (a > 0) { 
    myGlobalVar++; 
    a = 0; 
  } 
  return a; 
} 

void Function2 (void) { 
  if(myGlobalVar > 0) { 
    myGlobalVar = 42; 
  } else { 
    myGlobalVar = -1; 
  } 
} 


CONTENT COUPLING

Definition of Content Coupling

Two modules are content coupled if one directly references contents of the other. This can occur when you directly modify an instance variable of a instantiated class without using getter-setter methods. (like using public variables in a class/global variables without appropriate precautions). This should be avoided since any modification of data should be easy to find and easy to understand.

  • Generally, only assembler language allows content coupling. Most procedural and object-oriented programming languages make it difficult to implement content coupling.
  • Content coupling is also known as pathological coupling.
  • Avoid Content Coupling
  • Content coupling is the worst level of coupling. Content coupling should never be used when designing modules.

Example

int Func1 (int a) { 
  printf ("In Func1\n"); 
  a += 2; 
  goto F2A; 
  return a; 
} 

void Func2 (void) { 
  printf("In Func2\n"); 
  F2A: 
  printf("At Func2A\n"); 
} 

Determining Coupling Type

When two modules are coupled in more than one way, the coupling type is determined by the worst coupling type. For example, if two modules are data and control coupled, they are described as being control coupled.


Object Coupling

Object-oriented applications are comprised of systems of interacting objects. Objects must be coupled for these interactions to occur. In object-oriented applications, coupling can take place between the object and all objects external to it or coupling can occur among the items (i.e., methods, state, component objects) that comprise an individual object.

Object coupling is categorized into interface coupling and internal coupling. Interface coupling describes the coupling between an object and objects external to it through a public interface. Internal coupling describes how behaviors within an object interface with each other.