๐ง Guide: Coupling, Cohesion, and Connascence in Software Architecture
โก Quick Dive
Overview & Key Takeaways
In software design, understanding how parts of a system depend on and relate to one another is critical. This guide explores:
- Coupling: How tightly components depend on each other
- Cohesion: How well elements inside a module belong together
- Connascence: A deeper framework for analyzing interdependencies
๐ 1. Coupling: How Tightly Modules Are Connected
Coupling is the degree of interdependence between modules or components.
Types of Coupling (from worst to
๐ Extended Guide
In software design, understanding how parts of a system depend on and relate to one another is critical. This guide explores:
- Coupling: How tightly components depend on each other
- Cohesion: How well elements inside a module belong together
- Connascence: A deeper framework for analyzing interdependencies
๐ 1. Coupling: How Tightly Modules Are Connected
Coupling is the degree of interdependence between modules or components.
Types of Coupling (from worst to best):
| Type | Description |
|---|---|
| Content Coupling | One module directly accesses internal data of another |
| Common Coupling | Modules share global variables |
| Control Coupling | One module controls the flow of another |
| Stamp Coupling | Modules share only part of a data structure |
| Data Coupling | Modules communicate by passing only needed data |
| Message Coupling | Modules interact only via well-defined messages |
๐ด Example: Tight Coupling
// Bad: tight coupling to internal structure
class Order {
public List<Item> items;
}
class Invoice {
public double calculateTotal(Order order) {
return order.items.stream().mapToDouble(Item::getPrice).sum();
}
}
๐ข Better: Looser Coupling via Interface
interface Order {
double getTotal();
}
๐ฆ 2. Cohesion: How Focused a Module Is
Cohesion measures how functionally related the responsibilities of a single module are.
Types of Cohesion (from worst to best):
| Type | Description |
|---|---|
| Coincidental | Unrelated tasks grouped together |
| Logical | Similar tasks grouped but selected by flags |
| Temporal | Grouped by timing (e.g. init functions) |
| Procedural | Ordered steps grouped together |
| Communicational | Functions operate on same data |
| Functional | All operations contribute to one goal |
๐ด Low Cohesion Example
// Bad: unrelated responsibilities
class Utility {
void sendEmail() {}
void generatePDF() {}
void calculateDiscount() {}
}
๐ข High Cohesion Example
class InvoiceService {
void generatePDFInvoice() {}
void calculateInvoiceTotal() {}
}
๐ 3. Connascence: How Changes Propagate
Connascence is a more nuanced measure of dependency: if one part changes, must another?
Introduced by Meilir Page-Jones, it breaks down interdependency into types and strengths.
๐ Categories of Connascence
| Type | Meaning | Example |
|---|---|---|
| Name | Agree on names | Method parameters, variable names |
| Type | Agree on data types | Passing a String vs int |
| Meaning | Agree on semantic meaning | "Y" = yes, "N" = no |
| Position | Order of parameters matters | update(name, id) vs update(id, name) |
| Algorithm | Modules rely on the same algorithm | Hashing, compression |
| Execution | Must run in specific order | Init โ Validate โ Process |
| Timing | Must happen within time bounds | Race conditions, timeout logic |
๐ด High Connascence Example
// Position & Type Connascence
void createUser(String name, int age, boolean active);
A small change (e.g. swapping order or changing a type) breaks all callers.
๐ข Refactored to Reduce Connascence
record UserInput(String name, int age, boolean active);
void createUser(UserInput input);
โ๏ธ Comparison Summary
| Concept | Definition | Ideal Direction |
|---|---|---|
| Coupling | Degree of interdependence between modules | Lower |
| Cohesion | Degree of internal relatedness within a module | Higher |
| Connascence | How tightly two parts must change together | Reduce strength, increase locality |
๐งช When to Refactor
| Smell | What It Means | What to Do |
|---|---|---|
| Changing one module breaks many others | High coupling | Introduce interfaces, decouple |
| Class does too many unrelated things | Low cohesion | Split into cohesive components |
| A small change affects distant modules | High connascence, low locality | Encapsulate and reduce reach |