CSC/ECE 517 Summer 2008/wiki2 6 cc: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 3: Line 3:


==Introduction==
==Introduction==
Cohesion is a measure of how strongly-related and focused the various responsibilities of a software module are. It is usually expressed as “high” or “low” cohesion when being discussed. High cohesion is desired because it is robust, reliable, reusable and more understandable whereas low cohesion has the opposite of those traits – difficult to maintain, test,reuse and understand. With high cohesion comes low coupling. Coupling is the degree of dependence of   internal implementation between different modules – low coupling is where the module doesn't depend on what other module's internal implementation does thus a change in them won't affect the module whereas high coupling is where a change in one module might “break” other modules because they are highly dependent on eachother's internal implementations. This page will show you different types of cohesion and coupling and examples showing the “big picture” of them.  
[http://en.wikipedia.org/wiki/Cohesion_%28computer_science%29 Cohesion] is a measure of how strongly-related and focused the various responsibilities of a software module are. It is usually expressed as “high” or “low” cohesion when being discussed. High cohesion is desired because it is robust, reliable, reusable and more understandable whereas low cohesion has the opposite of those traits – difficult to maintain, test, reuse and understand. With high cohesion comes low coupling. Coupling is the degree of dependence of internal implementation between different modules – low coupling is where the module doesn't depend on what other module's internal implementation does thus a change in them won't affect the module whereas high coupling is where a change in one module might “break” other modules because they are highly dependent on eachother's internal implementations. This page will show you different types of cohesion and coupling and examples showing the “big picture” of them.  


== Cohesion ==
== Cohesion ==


Cohesion is categorized in “high” and “low” but  it is “measured” by how strongly-related or focused the responsibilities are for the class. In a highly-cohesive system, code readability and reusability is increased while complexity is kept manageable. A class of high cohesiveness could decrease its “cohesiveness” by carrying out more varied activities that have little in common and increasing complexity.
Cohesion is categorized in “high” and “low” but  it is “measured” by how strongly-related or focused the responsibilities are for the class. In a highly-cohesive system, code readability and reusability is increased while complexity is kept manageable. A class of high cohesiveness could decrease its “cohesiveness” by carrying out more varied activities that have little in common and increasing complexity. Below we describe the different types of cohesion arranged from highest to lowest cohesion.
 
=== Types of Cohesion ===
The types below are in order from "Highest" to "Lowest"


=====Functional Cohesion=====
=====Functional Cohesion=====
Functional cohesion describes a module that is designed to perform one and only one task.  A functionally cohesive module may contain multiple methods, but all of these methods are designed to help the user achieve a single task.  The following example illustrates functional cohesion.
Functional cohesion describes a module that is designed to perform one and only one task.  A functionally cohesive module may contain multiple methods, but all of these methods are designed to help the user achieve a single task.  The following example illustrates functional cohesion.


   public class Stack  
   public class Stack {
  {
     public Stack() {
     public Stack()  
    {
       // implementation
       // implementation
     }
     }
      
      
     public void push(Object obj)
     public void push(Object obj) {
    {
       // implementation
       // implementation
     }
     }
      
      
     public Object pop()
     public Object pop() {
    {
       // implementation
       // implementation
     }
     }
      
      
     public int getSize()
     public int getSize() {
    {
       // implementation
       // implementation
     }
     }
Line 39: Line 31:
    
    
=====Sequential Cohesion=====
=====Sequential Cohesion=====
Sequential cohesion describes modules whose operations are intended to executed in sequence with the output of each operation providing input to the subsequently executed operation.  The following example illustrates sequential cohesion [http://blogs.ittoolbox.com/eai/implementation/archives/design-principles-cohesion-16069].
Sequential cohesion describes modules whose operations are intended to be executed in sequence with the output of each operation providing input to the subsequently executed operation.  The following example illustrates sequential cohesion.


   class Cube {
   class Cube {
Line 53: Line 45:


===== Information cohesion =====
===== Information cohesion =====
Information cohesion can do several things with the same data - a class with various methods using same data.
Information cohesion can do several things with the same data - a class with various methods using same data.  The following example illustrates information cohesion.


     class Circle {
     class Circle {
Line 61: Line 53:
           public double getCircumference(){return 3.14*2*radius;}
           public double getCircumference(){return 3.14*2*radius;}
     }
     }
=====Communicational Cohesion=====
=====Communicational Cohesion=====
Communicational cohesion describes modules that perform multiple operations on the same input or output data [http://blogs.ittoolbox.com/eai/implementation/archives/design-principles-cohesion-16069].  The following example illustrates communication cohesion [http://www.waysys.com/ws_content_bl_pgssd_ch06.html].
Communicational cohesion describes modules that perform multiple operations on the same input or output data [http://blogs.ittoolbox.com/eai/implementation/archives/design-principles-cohesion-16069].  The following example illustrates communication cohesion [http://www.waysys.com/ws_content_bl_pgssd_ch06.html].


   public class CustomerInformation
   public class CustomerInformation {
  {
     public CustomerInformation(int accountNum) {
     public CustomerInformation(int accountNum)
    {
       // implementation
       // implementation
     }
     }
      
      
     public String getName()
     public String getName() {
    {
       // implementation
       // implementation
     }
     }
      
      
     public float getBalance()
     public float getBalance() {
    {
       // implementation
       // implementation
     }
     }
Line 85: Line 74:


=====Procedural Cohesion=====
=====Procedural Cohesion=====
Procedural cohesion is similar to sequential cohesion in that the operations exposed are typically grouped because they are executed within a sequence.  Unlike sequential cohesion however, the operations within a procedurally cohesive module can be somewhat unrelated and output from one operation is not necessarily use as input to a following operation.  The following example illustrates procedural cohesion.
Procedural cohesion is similar to sequential cohesion in that the operations exposed are typically grouped because they are executed within a sequence.  Unlike sequential cohesion however, the operations within a procedurally cohesive module can be somewhat unrelated and output from one operation is not necessarily used as input to a subsequently executed operation.  The following example illustrates procedural cohesion.


   public class Student
   public class Student {
  {
     public Student(int studentId) {
     public Student(int studentId)
    {
       // implementation
       // implementation
     }
     }
      
      
     public void LoadStudent()
     public void LoadStudent() {
    {
       // implementation
       // implementation
     }
     }
      
      
     public void UpdateGrades(int[] grades)
     public void UpdateGrades(int[] grades) {
    {
       // implementation
       // implementation
     }
     }
      
      
     public void UpdateAttendance(Date[] dates)
     public void UpdateAttendance(Date[] dates) {
    {
       // implementation
       // implementation
     }
     }
      
      
     public void SaveStudent()
     public void SaveStudent() {
    {
       // implementation
       // implementation
     }
     }
Line 118: Line 101:
Temporal cohesion describes a module that has several operations grouped by the fact that the operations are executed within temporal proximity.  The following example illustrates temporal cohesion.
Temporal cohesion describes a module that has several operations grouped by the fact that the operations are executed within temporal proximity.  The following example illustrates temporal cohesion.


   public class Startup
   public class Startup {
  {
     public void Initialize() {
     public void InitializeLogging()
      InitializeLogging();
     {
 
      InitializeUI();
 
      InitializeDb();
    }
      
    public void InitializeLogging() {
       // implementation
       // implementation
     }
     }
      
      
     public void InitializeUI()
     public void InitializeUI() {
    {
       // implementation
       // implementation
     }
     }
      
      
     public void InitializeDb()
     public void InitializeDb() {
    {
       // implementation
       // implementation
     }
     }
Line 137: Line 124:


=====Logical Cohesion=====
=====Logical Cohesion=====
Logical cohesion describes a module that groups operations because categorically they are related but the operations themselves are quite different.  Typically, these modules accept a control flag which indicates which operation to execute.  The following example illustrates logical cohesion [http://www.waysys.com/ws_content_bl_pgssd_ch06.html].
Logical cohesion describes a module that groups operations because categorically they are related but the operations themselves are quite different.  Typically, these modules accept a control flag which indicates which operation to execute.  The following example illustrates logical cohesion.


   public class DataStore
   public class DataStore {
  {
     public void SaveData(int destination, byte[] data) {
     public void SaveData(int destination, byte[] data)
       switch (destination) {
    {
       switch (destination)
      {
         default:
         default:
         case 0:
         case 0:
Line 160: Line 144:
     }
     }
      
      
     protected void SaveToDb(byte[] data)
     protected void SaveToDb(byte[] data) {
    {
       // implementation
       // implementation
     }
     }
      
      
     protected void SaveToFile(byte[] data)
     protected void SaveToFile(byte[] data) {
    {
       // implementation
       // implementation
     }
     }
      
      
     protected void SaveToWebService(byte[] data)
     protected void SaveToWebService(byte[] data) {
    {
       // implementation
       // implementation
     }
     }
Line 177: Line 158:


=====Coincidental Cohesion=====
=====Coincidental Cohesion=====
Coincidental cohesion describes a module whose operations are unrelated to one another and the module itself can be used to achieve several different types of tasks.  typically used to accomplish several unrelated tasks.  The following example illustrates coincidental cohesion [http://blogs.ittoolbox.com/eai/implementation/archives/design-principles-cohesion-16069].
Coincidental cohesion describes a module whose operations are unrelated to one another and the module itself can be used to achieve several different types of tasks.  The following example illustrates coincidental cohesion [http://blogs.ittoolbox.com/eai/implementation/archives/design-principles-cohesion-16069].


   public static class Math
   public static class Math {
  {
     public static int Add(int a, int b) {
     public static int Add(int a, int b)
    {
       // implementation
       // implementation
     }
     }
      
      
     public static int Subtract(int a, int b)
     public static int Subtract(int a, int b) {
    {
       // implementation
       // implementation
     }
     }
Line 194: Line 172:
   }
   }


===Advantages and disadvantages===
===Advantages and Disadvantages===
 
Cohesion is the idea that the module does a single task - be it calculating data, checking file etc. The "single task mindedness" drastically reduces code breaking when other modules are changed. If the module uses data from multiple other modules - if even one module changes or breaks, this module might need to be changed thus more time wasted. With single task modules, individual modules can be changed with very little problem.
Cohesion is the idea that the module does a single task - be it calculating data, checking file etc. The "single task mindedness" drastically reduces codes breaking when other modules are changed. If the module uses data from multiple other modules - if even one module changes or breaks, this module might need to be changed thus more time wasted. With single task modules, individual modules can be changed with very little problem.


==Coupling==
==Coupling==
 
[http://en.wikipedia.org/wiki/Coupling_%28computer_science%29 Coupling] is categorized low (loose or weak) or high (tight or strong). Low coupling is a relationship where one module interacts with another module through a stable interface and does not need to be concerned with other module's implementation. With low coupling, a change in one module will not require changes in the implementation of another module (since they are not dependent on each other). High coupling introduces problems like one module change into multiple module changes, difficulty of understanding the relationships and difficulty of testing and reusing individual modules because of high dependence. Low coupling facilitates high cohesion and vice versa. Low coupling may also reduce performance, and a highly-coupled system is sometimes desirable to achieve maximum efficiency. Below we describe the different types of coupling arranged from highest to lowest coupling.
Coupling is categorized low (loose and weak) or high(tight and strong). Low coupling is a relationship where one module interacts with another module through a stable interface and does not need to be concerned with other module's implementation. With low coupling, a change in one module will not require changes in the implementation of another module (since they are not dependent of each other). High coupling introduces problems like one module change into multiple module changes, difficulty of understanding the relationships and difficulty of testing and reusing individual modules because of high dependence. Low coupling facilitates high cohesion and vice versa. Low coupling may also reduce performance, and a highly-coupled system is sometimes desirable to achieve maximum efficiency.
 
===Types of coupling===
The types below are ordered from highest to lowest coupling.


=====Content coupling=====  
=====Content coupling=====  
Content coupling is when one module modifies or relies on the internal workings of another module. Therefore changing the way the second module produces data will lead to changing the dependent module.  
Content coupling is when one module modifies or relies on the internal workings of another module. Therefore changing the way the second module produces data will lead to changing the dependent module. The following example illustrates content coupling.


     class Circle {
     class Circle {
Line 217: Line 190:
         }
         }
     }
     }
Notice how the Square's getArea() was double but now changed to String. Now class Circle will get error because of incompatible types.  
 
Notice how the Square's <code>getArea()</code> was double but now changed to String. Now class <code>Circle</code> will get error because of incompatible types.  


=====Common coupling=====  
=====Common coupling=====  
Common coupling is when two modules share the same global variable.Changing the shared resource implies changing all the modules using it.  
Common coupling is when two modules share the same global variable. Changing the shared resource implies changing all the modules using it. The following example illustrates common coupling.


     class Circle{
     class Circle{
Line 227: Line 201:
         public double getCircumference() {return 2*3.14*radius;}
         public double getCircumference() {return 2*3.14*radius;}
     }
     }
Notice how the radius was double but now String. Now the getArea() and getCircumference() methods will break because the global variables they both use has been changed.


Notice how the radius was double but now String. Now the <code>getArea()</code> and <code>getCircumference()</code> methods will break because the global variables they both use has been changed.


=====Control coupling=====  
=====Control coupling=====  
Control coupling is one module controlling the logic of another, by passing it information on what to do.
Control coupling is one module controlling the logic of another, by passing it information on what to do.  The following example illustrates control coupling.


     class FileController {
     class FileController {
Line 247: Line 221:
         }
         }
       }
       }
This Class basically checks the file size and if it is over 5 megs it will tell processFile(boolean) to delete it, else it will close the file. So checkFile(File) is controlling processFile(boolean).
 
This Class basically checks the file size and if it is over 5 megs it will tell <code>processFile(boolean)</code> to delete it, else it will close the file. So <code>checkFile(File)</code> is controlling <code>processFile(boolean)</code>.


=====Stamp coupling=====
=====Stamp coupling=====
Stamp coupling is when modules share a composite data structure and use only a part of it, possibly a different part. This may lead to changing the way a module reads a record because a field, which the module doesn't need, has been modified.  
Stamp coupling is when modules share a composite data structure and use only a part of it, possibly a different part. This may lead to changing the way a module reads a record because a field, which the module doesn't need, has been modified.    The following example illustrates stamp coupling.


     class CarInfo {   
     class CarInfo {   
Line 266: Line 241:
       }
       }
     }
     }
WeightStation only needs carweight but if CarInfo ever changes its data and WeightStation happens to want to use something else errors could occur.
 
<code>WeightStation</code> only needs car weight but if <code>CarInfo</code> ever changes its data and <code>WeightStation</code> happens to want to use something else errors could occur.


=====Data coupling=====  
=====Data coupling=====  
Data coupling is when modules share data through, for example, parameters. Each datum is an elementary piece, and these are the only data which are shared.
Data coupling is when modules share data through, for example, parameters. Each datum is an elementary piece, and these are the only data which are shared.  The following example illustrates data coupling.


       Public double calculateRoot(int value) {
       public double calculateRoot(int value) {
           return value^(1/2);
           return value^(1/2);
       }
       }
   
   
=====Message coupling=====
=====Message coupling=====
This is the loosest type of coupling. Modules are not dependent on each other, instead they use a public interface to exchange parameter-less messages.
This is the loosest type of coupling. Modules are not dependent on each other, instead they use a public interface to exchange parameter-less messages.  The following example illustrates messag coupling.


       class superclass {
       class superclass {
           public void processData(){ module1.processData();}
           public void processData(){ module1.processData(); }
        }  
      }
       public Module2 {
       public Module2 {
           public void doSomething() { superclass.processData();}}
           public void doSomething() { superclass.processData(); }
 
      }


=====No coupling=====  
=====No coupling=====  
Line 354: Line 331:


====Demeter's Law====
====Demeter's Law====
[http://en.wikipedia.org/wiki/Law_of_Demeter Demeter's Law] is a design principle that when applied to object-oriented programming means that object A can reference object B but object A cannot use object B to reference object C.  Complying with this principle prevents object A from knowing that object B uses object C thereby reducing coupling.  If object A needs to access a function of object C then it is up to object B to expose an operation encapsulating the reference to object C.  The following example illustrates [http://javaboutique.internet.com/tutorials/coupcoh/index-2.html] how this could be done.
[http://en.wikipedia.org/wiki/Law_of_Demeter Demeter's Law] is a design principle that when applied to object-oriented programming means that object A can reference object B but object A cannot use object B to reference object C.  Complying with this principle prevents object A from knowing that object B uses object C thereby reducing coupling.  If object A needs to access a function of object C then it is up to object B to expose an operation encapsulating the reference to object C.  The following example [http://javaboutique.internet.com/tutorials/coupcoh/index-2.html] illustrates how this could be done.


   public float calculateTotal(Order order)
   public float calculateTotal(Order order) {
  {
     return order.getProducts().getTotalCost();
     return order.getProducts().getTotalCost();
   }
   }
Line 363: Line 339:
In the example object the object which implements <code>calculateTotal()</code> is calling <code>getTotalCost</code> on a <code>Products</code> object which is exposed through <code>order</code>.  An alternative to this approach would be for the order object to expose this functionality as suggested by the following example.
In the example object the object which implements <code>calculateTotal()</code> is calling <code>getTotalCost</code> on a <code>Products</code> object which is exposed through <code>order</code>.  An alternative to this approach would be for the order object to expose this functionality as suggested by the following example.


   public float calculateTotal(Order order)
   public float calculateTotal(Order order) {
  {
     return order.getTotalCost()
     return order.getTotalCost()
   }
   }
    
    
   public class Order
   public class Order {
  {
     // ...
     // ...
    
    
     public float getTotalCost()
     public float getTotalCost() {
    {
       return products.getTotalCost();
       return products.getTotalCost();
     }
     }
Line 383: Line 356:
Coupling and Cohesion goes hand in hand. On one hand cohesion wants modules to do exactly a single task thus reduces problems and making a module handle itself. Coupling is inevitably used by cohesion to complete tasks and thus could introduce problems. So good programming desires high cohesion and low coupling - modules that does one task without affecting other modules while at the sametime use as less data/objects from other modules as possible to have low coupling.
Coupling and Cohesion goes hand in hand. On one hand cohesion wants modules to do exactly a single task thus reduces problems and making a module handle itself. Coupling is inevitably used by cohesion to complete tasks and thus could introduce problems. So good programming desires high cohesion and low coupling - modules that does one task without affecting other modules while at the sametime use as less data/objects from other modules as possible to have low coupling.


== Also See ==
== See also ==
*[http://en.wikipedia.org/wiki/Cohesion_%28computer_science%29 Wikipedia: Cohesion]
*[http://en.wikipedia.org/wiki/Coupling_%28computer_science%29 Wikipedia: Coupling]
*[http://www.frontendart.com/monitor/help/node23.html Cohesion Metrics]
*[http://www.frontendart.com/monitor/help/node23.html Cohesion Metrics]
*[http://www.frontendart.com/monitor/help/node22.html Coupling Metrics]
*[http://www.frontendart.com/monitor/help/node22.html Coupling Metrics]

Revision as of 02:05, 26 June 2008

Cohesion and coupling. Cohesion and coupling are concepts that are reasonably easy to understand, but nonetheless, it is worthwhile to gather readable illustrations of where they apply. Browse the hundreds of Web pages that attempt to explain these concepts, picking your favorite examples. Categorize these examples, so that the reader will see the big picture, rather than just a set of redundant illustrations. Many of these pages mention related concepts; list some of them and explain how they relate to cohesion and coupling.


Introduction

Cohesion is a measure of how strongly-related and focused the various responsibilities of a software module are. It is usually expressed as “high” or “low” cohesion when being discussed. High cohesion is desired because it is robust, reliable, reusable and more understandable whereas low cohesion has the opposite of those traits – difficult to maintain, test, reuse and understand. With high cohesion comes low coupling. Coupling is the degree of dependence of internal implementation between different modules – low coupling is where the module doesn't depend on what other module's internal implementation does thus a change in them won't affect the module whereas high coupling is where a change in one module might “break” other modules because they are highly dependent on eachother's internal implementations. This page will show you different types of cohesion and coupling and examples showing the “big picture” of them.

Cohesion

Cohesion is categorized in “high” and “low” but it is “measured” by how strongly-related or focused the responsibilities are for the class. In a highly-cohesive system, code readability and reusability is increased while complexity is kept manageable. A class of high cohesiveness could decrease its “cohesiveness” by carrying out more varied activities that have little in common and increasing complexity. Below we describe the different types of cohesion arranged from highest to lowest cohesion.

Functional Cohesion

Functional cohesion describes a module that is designed to perform one and only one task. A functionally cohesive module may contain multiple methods, but all of these methods are designed to help the user achieve a single task. The following example illustrates functional cohesion.

 public class Stack {
   public Stack() {
     // implementation
   }
   
   public void push(Object obj) {
     // implementation
   }
   
   public Object pop() {
     // implementation
   }
   
   public int getSize() {
     // implementation
   }
 }
  
Sequential Cohesion

Sequential cohesion describes modules whose operations are intended to be executed in sequence with the output of each operation providing input to the subsequently executed operation. The following example illustrates sequential cohesion.

  class Cube {
      public ArrayList getInfo(){ 
             ArrayList tempList = new ArrayList();
             tempList.add(getArea());
             tempList.add(getVolume());
             return tempList;
      }
      public double getArea(){return 6*side*side;} 
      public double getVolume(){return side*side*side;}
   }
Information cohesion

Information cohesion can do several things with the same data - a class with various methods using same data. The following example illustrates information cohesion.

    class Circle {
         double radius;	      
         public double getArea(){return 3.14*radius*radius;}
         public double getDiameter(){return 2 * radius;}
         public double getCircumference(){return 3.14*2*radius;}
    }
Communicational Cohesion

Communicational cohesion describes modules that perform multiple operations on the same input or output data [1]. The following example illustrates communication cohesion [2].

 public class CustomerInformation {
   public CustomerInformation(int accountNum) {
     // implementation
   }
   
   public String getName() {
     // implementation
   }
   
   public float getBalance() {
     // implementation
   }
   
   // ...
 }
Procedural Cohesion

Procedural cohesion is similar to sequential cohesion in that the operations exposed are typically grouped because they are executed within a sequence. Unlike sequential cohesion however, the operations within a procedurally cohesive module can be somewhat unrelated and output from one operation is not necessarily used as input to a subsequently executed operation. The following example illustrates procedural cohesion.

 public class Student {
   public Student(int studentId) {
     // implementation
   }
   
   public void LoadStudent() {
     // implementation
   }
   
   public void UpdateGrades(int[] grades) {
     // implementation
   }
   
   public void UpdateAttendance(Date[] dates) {
     // implementation
   }
   
   public void SaveStudent() {
     // implementation
   }
 }
Temporal Cohesion

Temporal cohesion describes a module that has several operations grouped by the fact that the operations are executed within temporal proximity. The following example illustrates temporal cohesion.

 public class Startup {
   public void Initialize() {
      InitializeLogging();
      InitializeUI();
      InitializeDb();
   }
   
   public void InitializeLogging() {
     // implementation
   }
   
   public void InitializeUI() {
     // implementation
   }
   
   public void InitializeDb() {
     // implementation
   }
 }
Logical Cohesion

Logical cohesion describes a module that groups operations because categorically they are related but the operations themselves are quite different. Typically, these modules accept a control flag which indicates which operation to execute. The following example illustrates logical cohesion.

 public class DataStore {
   public void SaveData(int destination, byte[] data) {
     switch (destination) {
       default:
       case 0:
         SaveToDb(data)
         break;
       
       case 1:
         SaveToFile(data)
         break;
       
       case 2:
         SaveToWebService(data)
         break;
     }
   }
   
   protected void SaveToDb(byte[] data) {
     // implementation
   }
   
   protected void SaveToFile(byte[] data) {
     // implementation
   }
   
   protected void SaveToWebService(byte[] data) {
     // implementation
   }
 }
Coincidental Cohesion

Coincidental cohesion describes a module whose operations are unrelated to one another and the module itself can be used to achieve several different types of tasks. The following example illustrates coincidental cohesion [3].

 public static class Math {
   public static int Add(int a, int b) {
     // implementation
   }
   
   public static int Subtract(int a, int b) {
     // implementation
   }
   
   // ...
 }

Advantages and Disadvantages

Cohesion is the idea that the module does a single task - be it calculating data, checking file etc. The "single task mindedness" drastically reduces code breaking when other modules are changed. If the module uses data from multiple other modules - if even one module changes or breaks, this module might need to be changed thus more time wasted. With single task modules, individual modules can be changed with very little problem.

Coupling

Coupling is categorized low (loose or weak) or high (tight or strong). Low coupling is a relationship where one module interacts with another module through a stable interface and does not need to be concerned with other module's implementation. With low coupling, a change in one module will not require changes in the implementation of another module (since they are not dependent on each other). High coupling introduces problems like one module change into multiple module changes, difficulty of understanding the relationships and difficulty of testing and reusing individual modules because of high dependence. Low coupling facilitates high cohesion and vice versa. Low coupling may also reduce performance, and a highly-coupled system is sometimes desirable to achieve maximum efficiency. Below we describe the different types of coupling arranged from highest to lowest coupling.

Content coupling

Content coupling is when one module modifies or relies on the internal workings of another module. Therefore changing the way the second module produces data will lead to changing the dependent module. The following example illustrates content coupling.

   class Circle {
       public double getAreaDifference() { return getArea()-  square.getArea();}
   }
   class Square {
       public String getArea() {  //was double getArea()
            return area;   
       }
   }

Notice how the Square's getArea() was double but now changed to String. Now class Circle will get error because of incompatible types.

Common coupling

Common coupling is when two modules share the same global variable. Changing the shared resource implies changing all the modules using it. The following example illustrates common coupling.

    class Circle{
        String radius;//was double radius;
        public double getArea() {return 3.14*radius*radius;}
        public double getCircumference() {return 2*3.14*radius;}
    }

Notice how the radius was double but now String. Now the getArea() and getCircumference() methods will break because the global variables they both use has been changed.

Control coupling

Control coupling is one module controlling the logic of another, by passing it information on what to do. The following example illustrates control coupling.

   class FileController {
       public void checkFile(File file)  {
            if (file.size() >5000000)//5 megabytes  
                processFile(true); 
            else processFile(false); 	
        }
       public void processFile(boolean delete) {
            if (delete)
                deleteFile();      	
            else
                closeFile();
       }
     }

This Class basically checks the file size and if it is over 5 megs it will tell processFile(boolean) to delete it, else it will close the file. So checkFile(File) is controlling processFile(boolean).

Stamp coupling

Stamp coupling is when modules share a composite data structure and use only a part of it, possibly a different part. This may lead to changing the way a module reads a record because a field, which the module doesn't need, has been modified. The following example illustrates stamp coupling.

    class CarInfo {  
         String carType;  
         int numberOfWheels;
         double weight;
     }
    class WeightStation {
      public checkWeight(CarInfo carInfo) {
         if (carInfo.getWeight >4000) 
               System.out.println("car over weight limit");
         else
            System.out.println("car ok");
      }
   }

WeightStation only needs car weight but if CarInfo ever changes its data and WeightStation happens to want to use something else errors could occur.

Data coupling

Data coupling is when modules share data through, for example, parameters. Each datum is an elementary piece, and these are the only data which are shared. The following example illustrates data coupling.

      public double calculateRoot(int value) {
          return value^(1/2);
      }

Message coupling

This is the loosest type of coupling. Modules are not dependent on each other, instead they use a public interface to exchange parameter-less messages. The following example illustrates messag coupling.

      class superclass {
          public void processData(){ module1.processData(); }
      }

      public Module2 {
          public void doSomething() { superclass.processData(); }
      }
No coupling

Modules do not communicate at all with one another.

Advantages and disadvantages

Coupling allows interaction between different modules so more complicated tasks can be done. However, a strong coupling will decrease the flexibility of the modules and it will be harder to main and understand. If coupling is too tight, changing one module might have a "snowball effect" and will require changes of other modules that are dependent on it. Coupling must be used with caution and modules must use exactly what it needs and nothing more.

Related Concepts

Measuring Cohesion

The goal of well-designed systems is to have highly cohesive modules. Below are three metrics that can be used to determine the level of cohesion within a system.

Lack of Cohesion 1 (LCOM1)

 LCOM1 = (P > Q) ? (P – Q) : 0
 
 P = Total number of method pairs that do not use a common field of the class.
 Q = Total number of method pairs that access at least one common field of the class.

Lower LCOM1 values indicate higher cohesion and better overall design.

Lack of Cohesion 2 (LCOM2)

 LCOM2 = 1 – sum(mA)/(m*a)
 
 m = Total number of methods in the class.
 a = Total number of attributes in the class.
 mA = Total number of methods that access attribute a.
 sum(mA) = Sum of all mA for all attributes of the class.

Lower LCOM2 values indicate higher cohesion and better overall design. If the total number of methods or attributes is zero than the value of LCOM2 is undefined.

Lack of Cohesion 3 (LCOM3)

 LCOM3 = (m – sum(mA)/a) / (m – 1)
 
 m = Total number of methods in the class.
 a = Total number of attributes in the class.
 mA = Total number of methods that access attribute a.
 sum(mA) = Sum of all mA for all attributes of the class.

LCOM3 values greater than one indicates low cohesion and should be addressed. If the total number of methods is less than two or the number of attributes is zero than the value of LCOM3 is undefined.

Measuring Coupling

While it is impossible to avoid some level of coupling within systems, the goal is to reduce coupling as much as possible. Below are three metrics that can be used to determine the level of coupling within a system.

Coupling Between Objects (CBO)

 CBO = sum(t)
 
 t = Total number of types that are referenced by a particular class, not including any possible super-classes, primitive types or common framework classes.

Lower CBO values indicate lower coupling.

Data Abstraction Coupling (DAC)

 DAC = sum(a)
 
 a = Total number of types that are used for attribute declarations, not including primitive types, common framework classes, or types that are inherited from any possible super-classes.

Lower DC values indicate lower coupling.

Method Invocation Coupling (MIC)

 MIC = nMIC / (N – 1)
 
 N = Total number of classes defined within the project.
 nMIC = Total number of classes that receive a message from the target class.

Lower MIC values indicate lower coupling.

Demeter's Law

Demeter's Law is a design principle that when applied to object-oriented programming means that object A can reference object B but object A cannot use object B to reference object C. Complying with this principle prevents object A from knowing that object B uses object C thereby reducing coupling. If object A needs to access a function of object C then it is up to object B to expose an operation encapsulating the reference to object C. The following example [4] illustrates how this could be done.

 public float calculateTotal(Order order) {
    return order.getProducts().getTotalCost();
 }

In the example object the object which implements calculateTotal() is calling getTotalCost on a Products object which is exposed through order. An alternative to this approach would be for the order object to expose this functionality as suggested by the following example.

 public float calculateTotal(Order order) {
   return order.getTotalCost()
 }
 
 public class Order {
   // ...
 
   public float getTotalCost() {
     return products.getTotalCost();
   }
   
   // ...
 }

Conclusion

Coupling and Cohesion goes hand in hand. On one hand cohesion wants modules to do exactly a single task thus reduces problems and making a module handle itself. Coupling is inevitably used by cohesion to complete tasks and thus could introduce problems. So good programming desires high cohesion and low coupling - modules that does one task without affecting other modules while at the sametime use as less data/objects from other modules as possible to have low coupling.

See also

References

  1. http://blogs.ittoolbox.com/eai/implementation/archives/design-principles-cohesion-16069
  2. http://www.waysys.com/ws_content_bl_pgssd_ch06.html
  3. http://www.site.uottawa.ca:4321/oose/index.html#cohesion
  4. http://javaboutique.internet.com/tutorials/coupcoh/index-2.html
  5. http://bmrc.berkeley.edu/courseware/cs169/spring01/lectures/objects/sld001.htm
  6. http://blogs.ittoolbox.com/eai/implementation/archives/design-principles-coupling-data-and-otherwise-16061
  7. http://en.wikipedia.org/wiki/Cohesion_%28computer_science%29
  8. http://www.cs.sjsu.edu/faculty/pearce/modules/lectures/ood/metrics/Cohesion.htm
  9. http://class.ee.iastate.edu/berleant/home/Courses/SoftwareEngineering/CprE486fall2004/designModularity.htm
  10. http://www.eli.sdsu.edu/courses/spring99/cs535/notes/cohesion/cohesion.html#Heading8
  11. http://www.site.uottawa.ca:4321/oose/index.html#sequentialcohesion