Core Idea

Connascence is a sophisticated metric for measuring the degree to which one software component depends on another. It answers the question: “If I change this code, what else breaks?”

What Is Connascence?

Connascence refines the traditional concept of Coupling by providing a nuanced taxonomy of dependencies:

  • While coupling tells us that modules are connected
  • Connascence tells us how they are connected
  • Shows what kinds of changes will propagate across module boundaries

The term “connascence” means “born together” or “common birth”:

  • When two things are connascent, changing one necessitates changing the other to maintain correctness
  • Introduced by Meilir Page-Jones to capture subtleties that simple cohesion and coupling metrics miss

Types of Connascence

Connascence exists on a spectrum from static (detectable at compile time) to dynamic (only observable at runtime):

Static Connascence includes dependencies like:

  • Connascence of Name: Multiple components must agree on a name (method names, variable names)
  • Connascence of Type: Multiple components must agree on a type
  • Connascence of Meaning: Multiple components must agree on the interpretation of values (e.g., “true means success”)
  • Connascence of Position: Multiple components must agree on the order of values (method parameters)
  • Connascence of Algorithm: Multiple components must agree on a particular algorithm

Dynamic Connascence includes dependencies like:

  • Connascence of Execution: The order of execution matters
  • Connascence of Timing: The timing of execution matters
  • Connascence of Values: Multiple components must agree on certain values at runtime
  • Connascence of Identity: Multiple components must reference the same entity

Dynamic connascence is more problematic because it cannot be detected through static analysis or compile-time checks—it manifests only when the system runs.

The Connascence Hierarchy

Page-Jones established principles for managing connascence:

  1. Minimize connascence across module boundaries — Strong boundaries reduce propagation of change
  2. Maximize connascence within modules — Related code should be tightly connected
  3. Convert strong forms to weaker forms — Replace dynamic connascence with static connascence where possible

For example, converting “connascence of meaning” (where a boolean flag’s value has implicit meaning) to “connascence of name” (using an enum with explicit named values) makes dependencies more explicit and easier to maintain.

Why This Matters

Connascence provides architectural guidance that simple coupling metrics cannot:

  • Explains why certain refactorings reduce maintenance burden
  • Reveals hidden dependencies that cause seemingly unrelated code to break together
  • Guides decisions about where to draw module boundaries
  • Helps identify the strongest, most fragile dependencies in a system
  • Enables prioritizing refactoring efforts to convert dependencies to weaker, more maintainable forms

Sources

  • Richards, Mark and Neal Ford (2020). Fundamentals of Software Architecture: An Engineering Approach. O’Reilly Media. ISBN: 978-1-492-04345-4.

  • Page-Jones, Meilir (1992). “Comparing Techniques by Means of Encapsulation and Connascence.” Communications of the ACM, Vol. 35, No. 9, pp. 147-151.

    • Original introduction of connascence concept
    • DOI: 10.1145/130994.131004

Note

This content was drafted with assistance from AI tools for research, organization, and initial content generation. All final content has been reviewed, fact-checked, and edited by the author to ensure accuracy and alignment with the author’s intentions and perspective.