In computer science, coupling or dependency is the degree to which each program module relies on each one of the other modules.
Coupling is usually contrasted with cohesion. Low coupling often correlates with high cohesion, and vice versa. The software quality metrics of coupling and cohesion were invented by Larry Constantine, original developer of Structured Design was also an early proponent of these concepts (see also SSADM).
Coupling can be "low" (also "loose" and "weak") or "high" (also "tight" and "strong"). Low coupling refers to a relationship in which one module interacts with another module through a stable interface and does not need to be concerned with the other module's internal implementation (see Information Hiding
). With low coupling, a change in one module will not require a change in the implementation of another module. Low coupling is often a sign of a well-structured computer system
, and when combined with high cohesion, supports the general goals of high readability and maintainability.
Systems that do not exhibit low coupling might experience the following developmental difficulties:
- Change in one module forces a ripple of changes in other modules.
- Modules are difficult to understand in isolation.
- Modules are difficult to reuse or test because dependent modules must be included.
The concept of coupling is usually related to the concept of cohesion: low coupling facilitates high cohesion, and vice versa. For example, one approach to increasing cohesion is functional design, which seeks to limit the responsibilities of modules along funccally, coupling increases between two classes A and B if:
- A has an attribute that refers to (is of type) B.
- A calls on services of an object B.
- A has a method which references B (via return type or parameter).
- A is a subclass of (or implements) class B.
Low coupling may also reduce performance, and a highly-coupled system is sometimes desirable to achieve maximum efficiency. Regardless, in many modern computing systems, the cost of reduced performance is often seen as a worthy trade for the benefits to the software development process that result from low coupling.
Types of coupling
Some types of coupling, in order of highest to lowest coupling, are as follows:Content coupling (high): Content coupling is when one module modifies or relies on the internal workings of another module (e.g. accessing local data of another module).
- Therefore changing the way the second module produces data (location, type, timing) will lead to changing the dependent module.Common coupling: Common coupling is when two modules share the same global data (e.g. a global variable).
- Changing the shared resource implies changing all the modules using it.External coupling: External coupling occurs when two modules share an externally imposed data format, communication protocol, or device interface.Control coupling: Control coupling is one module controlling the logic of another, by passing it information on what to do (e.g. passing a what-to-do flag).Stamp coupling (Data-structured coupling): Stamp coupling is when modules share a composite data structure and use only a part of it, possibly a different part (e.g. passing a whole record to a function which only needs one field of it).
- This may lead to changing the way a module reads a record because a field, which the module doesn't need, has been modified.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 (e.g. passing an integer to a function which computes a square root).Message coupling (low): 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 (or events, see Message passing).No coupling: Modules do not communicate at all with one another.
Subclass Coupling: Describes the relationship between a class and its parent. The class is connected to its parent, but the parent isn't connected to the child.Temporal coupling: When two actions are bundled together into one module just because they happen to occur at the same time.
High cohesion and low coupling are attributes of good design.
Coupling in Software Engineering describes a version of metrics associated with this concept.
For data and control flow coupling:
di = number of input data parameters
ci = number of input control parameters
do = number of output data parameters
co = number of output control parameters
For global coupling:
gd = number of global variables used as data
gc = number of global variables used as control
For environmental coupling:
w = number of modules called (fan-out)
r = number of modules calling the module under consideration (fan-in)
Coupling (C) = 1 - 1/(di + 2·ci + do + 2·co + gd + 2·gc + w + r)
"1 - ..." makes the value larger the more coupled the module is. This number
ranges from approximately 0.66 (low coupling) to 1.0 (highly coupled)
For example, if a module has only a single input and output data parameter
C = 1 - 1/(1+0+1+0+0+0+1+0) = 1 - 1/3 = 0.67
If a module has 5 input and output data parameters, an equal number of control parameters, and accesses 10 items of global data, with a fan-in of 3 and a fan-out of 4,
C = 1 - 1/(5 + 2·5 + 5 + 2·5 + 10 + 0 + 3 + 4) = 0.98
Very loosely coupled systems have the added advantage that they tend to build more quickly. This is due to the low amounts of inter-module dependency. Systems such as CORBA
allow objects to communicate with each other without having to know anything about the other's implementation. Both these systems even allow for objects to communicate with objects written in other languages. The fact that the objects may be built independently reduces the amount of recompilation required when changes are applied.
Explicit and implicit dependencies
Hidden, implicit dependencies make code hard to test and hard to reuse. So, one can explicitly declare dependencies.