Coupling & Cohesion

Michael L. Collard, Ph.D.

Department of Computer Science, The University of Akron

Layered Systems

  • system
  • subsystem
  • package/module
  • class/file
  • attributes & operations
  • local variables

Why Separate into Multiple Elements?

  • Easier to understand
  • Increase reuse (internal and external)
  • Reduce (maintenance) costs for fixes and enhancements
  • Simplify testing
  • Permit replacement

Desired Interaction

  • Maximize internal interaction (intramural) among subelements (cohesion)
    • easier to comprehend
    • easier to test
  • Minimize external interaction (extramural) with other elements (coupling)
    • easier to comprehend
    • easier to test
    • can be used independently
    • easier to replace

Cohesion

degree of connectivity among the elements of a single module, and in object-oriented design, a single class/object

  • Internal measure on an individual class/object/module/method
  • How to measure?

Types of Cohesion

  • Informational (best)
  • Functional (best)
  • Sequential (better)
  • Communicational (better)
  • Procedural
  • Temporal
  • Logical
  • Coincidental (worst)

Coincidental Cohesion

  • Performs multiple, completely unrelated actions
  • May be based on factors outside of the design: personnel, company organization, history, avoidance of small modules
  • No reusability, difficult to maintain or enhance

Logical Cohesion

  • Performs a series of related actions, one of which is selected by the calling module
  • Parts have a logical association, but the association is not the primary logical association
  • Primary logical association should be based on the highest level of abstraction the element is involved in

Logical Cohesion (cont)

  • Often includes both high and low-level actions (in terms of abstraction) in the same class
  • Often includes unused parameters for certain uses
  • Difficult to understand interface. Many unrelated actions
  • In OO we put methods near the abstract concept that they work on

Temporal Cohesion

  • Perform a series of actions that are related by time occurrence
  • Often happens in initialization or shutdown
  • Degrades to Logical Cohesion if time of action changes
  • Addition of subsystems may require additions to multiple modules, e.g., shutdown, startup, etc.
  • In OO we build time occurrence actions into the class. Externally we control lifetime.

Procedural Cohesion

  • Action based on the ordering of steps
  • Related by usage in ordering
  • Changes to the ordering of steps or purpose of steps requires changing the element abstraction
  • Situations where this particular sequence applies are often limited
  • Each element, including methods/operations, should have one cohesive action

Communicational Cohesion

  • Works on all the same data
  • Action based on the ordering of steps
  • Actions are related but still not completely separated
  • Element cannot be reused
  • May be the highest cohesion possible/desirable

Sequential Cohesion

FormatAndValidate:
    input raw data
    format data
    validate data
    return data
End
  • Actions are placed together because they have to be performed in order
  • Not necessarily bad, unless there is not a crisp abstraction represented in the name of the method

Functional Cohesion

  • Element (methods) that performs a single action or achieves a single goal
  • Maintenance involves entire element
  • High reuse because the element is completely independent (in its actions) of other elements
  • Easily replaced for performance, testing, platform changes, etc.
  • Superior

Informational Cohesion

  • Performs a number of actions
  • Each action has its own entry point and independent code
  • All actions are performed on a shared data structure
  • Truly Object-Oriented
  • Superior

Coupling

  • Dependency between elements
  • Degree or reliance between elements
  • Increasing cohesion may lead to more coupling (Why?)
  • Entropy of systems and designs increases coupling
  • Coupling needs to be limited and controlled

States of Coupling

  • tightly coupled
    • High degree of coupling between elements
    • Very difficult develop/test/maintain/use separately
  • loosely coupled
    • Low degree of coupling between elements
    • Much easier to develop/test/maintain/use separately
  • decoupled
    • Elements with none to very little coupling between elements
    • Can be developed/tested/maintained/used separately
    • Common refactoring activity

Types of Coupling

  • Message Coupling (very best)
  • Data Coupling (best)
  • Stamp Coupling
  • Control Coupling
  • Common Coupling
  • Content Coupling (worst)

Content Coupling

  • A module directly references the content of another module:
    • One module p modifies a statement of another module q
    • One module p references or alters local data of another module q
    • One module p branches into another module q

Content Coupling (cont)

  • Content coupled modules are inextricably interlinked
    • Change to module q requires a change to module p including recompilation
    • Reusing module p requires using module q
  • Exposing data members as public is a form of this

Common Coupling Example

students.hpp

register.cpp

deregister.cpp

Common Coupling

  • Using global variables, i.e., global coupling
  • All modules have read/write access to a global data block
  • Modules exchange data using the global data block (instead of arguments)
  • Single module with write access where all other modules have read access is not common coupling

Common Coupling (cont)

  • To determine why a variable has a particular state have to examine all the modules
  • Side effects, so all the code in a function needs to be examined
  • Changes to the data layout in one module require changes in all other modules
  • Must declare identical list of global variables for module reuse
  • Module is exposed to more data then is needed

Control Coupling

  • One module passes an element of control to another module
  • One module explicitly controls the logic of another
    • Control switch is passed as an argument
    • Module p passes an argument to module q that directly tells it what control structure path to take

Control Coupling (cont)

  • Control coupling?
    • Module p calls module q and q passes a flag back to p that indicates an error
    • Module p calls module q and q passes a flag back to p that tells p that it must output the error
  • Independent reuse is not possible
  • Modules should pass data and leave control path decisions private to a module

Stamp Coupling

  • One module passes more data then needed to another module
    • void swap(int v[], int i, int j);
    • double calcsalary(Employee);
  • Often involves records (structs) with lots of fields
  • Entire record is passed, but only a few fields are used
  • Efficiency considerations?

Data Coupling

  • Only required data is passed from one module to another
    • swap(v[i], v[j]);
    • calcSalary(employee.PayInfo);
  • All arguments are homogenous data items
    • simple data type
    • complex data type, but all parts are used
  • Allows for comprehension, reuse, maintenance, security, …

Message Coupling

  • Parameters are passed via a non-private data format
  • Most flexible, since data can be generated using any language, tool, etc.
  • Requests can be stored, cached
  • All arguments are homogenous data items
    • simple data type
    • complex data type, but all parts are used
  • Allows for comprehension, reuse, maintenance, security, …
  • Potential performance overhead (?)

Tightly Coupled

  • Change in one module leads to changes in other modules
  • Difficult to test/reuse individual parts
  • Difficult to assemble separately
  • Difficult to add additional feature/use of the system

Loosely Coupled

  • Allows independent changes to modules
  • Easily test/reuse individual parts
  • Easier to assemble separately

  • If modules cannot be loosely coupled, perhaps they should be combined (or packaged together), or used in very specific ways

Other Types of Coupling

  • Subclass Coupling - Between derived and base class

Advantages of Tightly-Coupled Modules

  • Obtain only the data that is needed. E.g., parsing source code for a specific query
  • Directly use the data with no need to translate to/from a data format
  • Layers can be skipped that are not needed. E.g., ISO 7-level network model vs. TCP/IP
  • All the features of a specific API can be used. E.g., writing code for mySQL instead of a generic database format (ODBC)
  • Decoupling leads to abstractions, which can make the programming task more difficult then direct use

In general, tightly-coupled modules can be more efficient, at the cost of flexibility