Instiq
Chapter 3 · Software design·v1.0.0·Updated 7/11/2026·~15 min

What's changed: Initial version

3.1Principles of module decomposition

Key points

Covers the two yardsticks for module-decomposition quality: cohesion (the strength of relatedness among elements within a module—higher is better) and coupling (the strength of dependency between modules—lower is better), including their orderings and kinds, and how to diagnose the root cause of "a single change rippling across a wide area" using these two axes and decide on a fix.

The starting point of software architecture design is deciding how to decompose a system into modules. The quality of that decomposition can be evaluated objectively—not by feel—using two measures: cohesion and coupling. What matters to a system architect is not memorizing the names of these measures but being able to diagnose whether a design where a single change ripples elsewhere is a cohesion problem or a coupling problem, and choose a concrete remedy.

3.1.1Cohesion: cohesiveness within a module

  • Cohesion measures how strongly the elements (processing, data) inside a module are related to one another and focused on a single purpose. The higher the cohesion, the better the design is considered to be.
  • Representative kinds, from weakest to strongest, include: coincidental cohesion (elements bundled into one module with little functional relation—the weakest), procedural cohesion (elements grouped merely by execution order), and so on, up to functional cohesion (a module performs exactly one well-defined function—the strongest and best). The stronger the cohesion, the more a module's purpose can be described in a single sentence, and the narrower the blast radius of any change to it.

3.1.2Coupling: dependency between modules

  • Coupling measures how strongly modules depend on one another. The lower the coupling, the better the design is considered to be—note that this is the opposite direction of evaluation from cohesion.
  • Representative kinds, from strongest (worst) to weakest, include: content coupling, where one module directly references or rewrites another's internal structure (the strongest and worst); common coupling, sharing global variables; control coupling, passing a control flag as an argument to steer the other module's internal branching; and so on, down to data coupling, exchanging only the necessary data items as arguments (the weakest and best). The weaker the coupling, the less a change to another module's internal implementation affects your own module.
  • Cohesion and coupling are not independent measures—they correlate: re-decomposing a system into modules with high functional cohesion tends to naturally clarify each module's responsibility and also weaken coupling down to data coupling. Conversely, a module with coincidental cohesion, formed by forcibly bundling unrelated processing, tends to end up with content or common coupling to other modules as well.
Exam point

Most-tested: "cohesion should be high while coupling should be low (opposite directions of evaluation)," "the best kind of cohesion is functional cohesion and the worst is coincidental cohesion," and "the best kind of coupling is data coupling and the worst is content coupling." The single most important pitfall is reversing the "good direction" of the two measures—coupling being high is never good.

Suppose a system architect is assigned to maintain an existing order-management system. The field reports that "we changed only the shipping-fee calculation rule, but inventory allocation and invoice issuance started behaving strangely too." Investigating the source, the architect finds that a single massive module, OrderProcessor, crams together four functions that are inherently unrelated—order acceptance, inventory allocation, shipping-fee calculation, and invoice issuance (close to coincidental cohesion). Worse, these four pieces of processing exchange state through a global variable, orderContext, shared within the module (common coupling): when the shipping-fee logic rewrites orderContext, the subsequent invoice-issuance logic reads that same value, so unrelated functions end up unintentionally affecting one another. This is the root cause of "a single change rippling widely." The fix is to first split OrderProcessor into functionally cohesive modules, each with a single responsibility—order acceptance, inventory allocation, shipping-fee calculation, invoice issuance—and then eliminate the commonly-coupled orderContext, replacing inter-module dependencies with data coupling, where only the necessary data items are passed as arguments. With this change, altering the internal logic of the shipping-fee module no longer affects the invoice-issuance module, as long as the data format (interface) passed between them stays unchanged. Whenever you see the symptom of a change's impact unexpectedly spreading, the architect's job is to diagnose the root cause from both angles—cohesion (are unrelated functions crammed together?) and coupling (is there dependency through global state or internal structure?) and choose the remedy accordingly.

MeasureBestWorstDirection of evaluation
CohesionFunctional cohesion (a single well-defined function)Coincidental cohesion (unrelated processing bundled together)Higher is better
CouplingData coupling (only necessary data items passed as arguments)Content coupling (directly referencing/rewriting internal structure)Lower is better
Warning

Trap: "Coupling, like cohesion, is better when higher" is wrong—coupling should be low (the opposite direction of evaluation from cohesion). Also wrong: "common coupling, which shares state via global variables, is a recommended design because it reduces argument passing and is efficient"—common coupling is a strong dependency whose impact from change is hard to predict, and it should in principle be weakened down to data coupling.

Cohesion/coupling.
What makes a good split

3.1.3Section summary

  • Cohesion should be as high as possible; the best kind is functional cohesion and the worst is coincidental cohesion
  • Coupling should be as low as possible; the best kind is data coupling and the worst is content coupling (the direction of evaluation is opposite to cohesion)
  • Diagnose the symptom of "a single change rippling widely" from both angles: low cohesion from bundling unrelated functions, and high coupling from dependency on global state or internal structure

Sign in to track progress — Log in.

Quick check

(just a quick review)

Q1. Changing a single shipping-fee calculation rule in an order-management system broke inventory allocation and invoice issuance too. Investigation found four unrelated functions coexisting in one module, exchanging state through a shared global variable. What is the most appropriate root cause of this symptom?

Q2. What is the most appropriate approach to fix the order-management system from the previous question?

Q3. A design has processing in module A directly reference and rewrite module B's internal data structure. What is the most appropriate evaluation of this coupling and the priority direction for improvement?

Check your understandingPractice questions for Chapter 3: Software design