Siksha Sarovar

Siksha Sarovar (sikshasarovar.com) is a free educational web application that helps students in India learn programming and prepare for academic and competitive exams. The platform offers structured coding courses (C, C++, Python, Java, HTML, CSS, PHP, Power BI, AI, Machine Learning, Data Science), complete university curriculum notes for BCA/MCA students with previous year question papers, Class 10 and Class 12 CBSE/HBSE school notes, and dedicated preparation material for SSC, UPSC, Banking, Railway and other government exams. Browsing the site is completely free and requires no account. Users may optionally sign in with Google solely to save their learning progress, quiz scores and personal preferences across devices.

Privacy Policy | Terms of Service | Contact Siksha Sarovar | About Siksha Sarovar

v4.0.9 · PWA
Siksha Sarovar logo
Siksha Sarovar
Your Learning Universe

Siksha Sarovar is a free e-learning platform for coding courses, BCA university notes and competitive exam preparation. Optional Google sign-in saves your learning progress across devices.

Initializing knowledge base…
Compiling modules 0%

3.1 Software Design — Cohesion, Coupling & Design Principles

Lesson 15 of 24 in the free Software Engineering notes on Siksha Sarovar, written by Rohit Jangra.

3.1 Software Design — Cohesion, Coupling & Design Principles

What is software design?

Design is the bridge between requirements (what) and implementation (how). It transforms the SRS into:

  • Architecture — high-level structure: subsystems, components, communication
  • Module design — each component's internal structure, data, interfaces
  • Data design — database schema, file formats
  • Interface design — APIs, user interface specs
Requirements (SRS) ─► [DESIGN] ─► Code
                        │
                        ├── Architectural design (HLD)
                        ├── Module / detailed design (LLD)
                        ├── Data design
                        └── Interface design

The output is a Software Design Document (SDD).

---

Fundamental Design Principles

These principles, distilled from decades of software engineering practice, guide every design decision:

PrincipleDescriptionExample
ModularityBreak the system into manageable, well-defined modulesLibrary = {Member, Book, Loan, Report} modules
AbstractionHide implementation, expose only essential interfaceA "Stack" exposes push/pop; doesn't reveal it's an array
Information hidingEach module hides its internal state from othersMember module owns the member table — no one else touches it
EncapsulationBundle data and operations togetherA Java class encapsulating its fields with getters/setters
Functional independenceHigh cohesion + low couplingEach module does one thing well
RefinementTop-down decomposition"Issue Book" → check eligibility → check availability → create loan
Separation of concernsDifferent aspects in different modulesUI ≠ business logic ≠ data access
Anticipation of changeMake likely-to-change parts replaceableCurrency code in config, not hard-coded
Exam tip: Functional independence is the most important principle and is measured by cohesion (within a module) and coupling (between modules).

---

Cohesion — "togetherness" within a module

Cohesion is a measure of how strongly the elements within a single module belong together. Higher cohesion is better — each module should do one well-defined job.

Stevens, Myers and Constantine (1974) defined 7 levels of cohesion, ranked worst to best:

LevelNameDefinitionExample
1 (worst)CoincidentalElements are grouped randomly"Utility" module containing date helpers, network sniffer, log rotator
2LogicalElements perform similar logical tasksInput handler that reads from keyboard, file, network — based on a flag
3TemporalElements executed at the same time"Initialization" module — open log, allocate buffers, set defaults
4ProceduralElements follow a sequence of executionRead input → process → print output
5CommunicationalElements act on the same dataProcess all calculations on a customer record
6SequentialOutput of one element is input of nextRead raw scan → de-skew → OCR → validate
7 (best)FunctionalAll elements contribute to a single, well-defined taskcalculateInterest() does nothing but interest

Memory aid (acronym)

Come Let's Take Physics Course Since Final exams (Coincidental, Logical, Temporal, Procedural, Communicational, Sequential, Functional)

Why high cohesion matters

  • A high-cohesion module is easy to name — its name describes one job
  • It is easy to test — one job means a focused test suite
  • It is easy to reuse — clear contract
  • It is easy to maintain — changes are localised

---

Coupling — "dependence between modules"

Coupling is a measure of how strongly modules depend on each other. Lower coupling is better — modules should be able to change independently.

5 levels of coupling, worst to best:

LevelNameDefinitionExample
1 (worst)Content couplingOne module modifies another's internal data or codeGoto into the middle of another function; access private vars
2Common couplingModules share global dataMultiple modules read/write a global config variable
3Control couplingOne module passes a flag that controls another's behaviourprocess(flag) where flag changes the algorithm
4Stamp couplingModules pass entire structures when only parts are neededupdateAge(student) when only age is needed
5 (best)Data couplingModules exchange only needed data itemsupdateAge(id, age) — minimal interface

Additional categories (sometimes listed)

LevelNameDescription
External couplingDependence on external file format or protocolHard-coded XML format
Message coupling (OO)Lowest in OO — modules communicate only via method callsSending message account.deposit(100)

Memory aid

Could Cats Chase Some Dogs? (Content, Common, Control, Stamp, Data — worst to best)

Why low coupling matters

  • Modules are independently testable
  • Modules are independently modifiable
  • Modules can be replaced without affecting others
  • Bugs are localised

---

Cohesion vs Coupling — quick comparison

AspectCohesionCoupling
Refers toWithin a moduleBetween modules
DirectionShould be highShould be low
MeasuresHow focused a module isHow dependent modules are
Goal of good designMaximiseMinimise
Golden rule: High cohesion, low coupling. Every good design optimises this trade-off.

---

Classification of Design

Architectural styles

StyleDescriptionExample
Layered (n-tier)Stack of layers, each uses the one belowPresentation → Business → Data
Client-ServerServer provides services, clients consumeDatabase server, web server
Pipe-and-FilterStream-processing componentsUnix pipes; ETL pipelines
Event-DrivenComponents react to eventsUI frameworks; pub-sub
MicroservicesSmall autonomous services communicate over networkNetflix, Amazon
Repository / BlackboardComponents communicate via shared data storeCompiler symbol table
MVC (Model-View-Controller)Separates data, presentation, controlMost web frameworks

Design strategies

StrategyProcess
Top-downStart from system, decompose into sub-problems
Bottom-upStart with utilities, compose into system
Hybrid (sandwich)Middle-out: identify components, then top-down and bottom-up
Object-oriented design (OOD)Identify classes and their interactions
Function-oriented design (FOD)Identify functions and data flows (uses DFD)

---

Structured Design — Function-Oriented

Originating with Yourdon & Constantine (1979), structured design is the classical function-oriented approach:

1. Draw DFD for the system.
2. Identify transform / transaction centres.
3. Map the DFD into a structure chart (modules + calls).
4. Refine each module independently.

Structure chart is a tree of modules:

       Library System
       /     |       \
    Member  Book    Loan
    /  \    / \     / | \
   Add  Get Add Get Issue Return Renew

Each branch is a module; arrows can indicate data flow ("data couples") and control ("control couples").

---

Key Terms — Lesson 3.1

The vocabulary below covers cohesion, coupling, design principles, architectural styles, and the OO design extensions you need to be fluent in for any Unit-III PYQ.

Software Design — The phase that transforms requirements (SRS) into a blueprint (SDD) for construction — defining the architecture, modules, data structures, interfaces, and algorithms. Design sits between requirements and implementation in the SDLC.

Software Design Document (SDD) — The deliverable of the design phase. Typically split into High-Level Design (HLD) describing major subsystems and their interfaces, and Low-Level Design (LLD) describing internal class/method designs, data structures, and algorithms.

Architectural Design / High-Level Design (HLD) — The system-wide design decisions: choice of architectural style (layered, microservices, MVC, etc.), major subsystems, their responsibilities, and how they communicate. HLD answers "what are the boxes and arrows?"

Detailed Design / Low-Level Design (LLD) — The internal design of each component identified in HLD — classes, methods, data structures, algorithms, error-handling. LLD answers "what is inside each box?"

Modularity — The principle of decomposing the system into manageable, self-contained modules with well-defined interfaces. Modularity is the meta-principle behind almost every other design idea — testability, parallel development, replaceability, and maintainability all depend on it.

Abstraction — Representing essential characteristics while hiding implementation details. A Stack abstraction exposes push and pop; consumers don't need to know it is implemented as an array or a linked list. Abstraction is the cognitive lever that lets humans manage large systems.

Information Hiding (Parnas) — David Parnas's 1972 principle: each module should encapsulate a design decision and hide it from the rest of the system. The design decisions most likely to change should be hidden behind the most rigid module boundaries. The original justification for OO encapsulation.

Encapsulation — Bundling data and the operations on that data together inside a single unit (a class or module), and protecting the data from external access. Encapsulation is the OO mechanism that delivers information hiding.

Separation of Concerns (Dijkstra) — Edsger Dijkstra's principle that different concerns (UI, business logic, data access, security) should be handled in different modules. The three-tier architecture, MVC, and hexagonal architecture all operationalise this principle.

Cohesion — A measure of how strongly the elements within a single module belong together — what fraction of the module's contents serve a single, well-defined purpose. Higher cohesion is better. Stevens-Myers-Constantine (1974) ranked cohesion in seven levels from coincidental (worst) to functional (best).

Functional Cohesion — The best level of cohesion — every element of the module contributes to a single, well-defined task. A calculateInterest() function that does nothing but compute interest, or a UserRepository class that does nothing but persist users, exhibits functional cohesion.

Coincidental Cohesion — The worst level of cohesion — module elements are grouped randomly with no meaningful relationship. The classic example is a "utility" module containing a date formatter, a network sniffer, and a log rotator. Coincidental cohesion signals a module whose name cannot capture what it does.

Coupling — A measure of how strongly modules depend on each other — how much one module knows about another's internals and how easily one can change without breaking the other. Lower coupling is better. Coupling has five canonical levels from content (worst) to data (best).

Content Coupling — The worst level of coupling — one module directly accesses or modifies another's internal data or code. A GOTO into the middle of another function or a struct-field write by an outsider both exhibit content coupling. Almost always a sign of broken modularity.

Data Coupling — The best level of coupling — modules exchange only the specific data items needed, via well-defined parameters. updateAge(id, age) is data-coupled; updateUser(wholeUserObject) (when only age matters) is stamp-coupled.

Stamp Coupling — Modules pass entire data structures when only a few fields are needed. Wasteful and creates unnecessary coupling — change the struct and every caller may need to change.

Control Coupling — One module passes a flag or command that controls another's internal behaviourprocess(mode) where mode selects between algorithms. Control coupling forces the caller to know the callee's internal options.

Common Coupling — Modules share global variables. Any module can read or write the shared state; reasoning about correctness becomes a whole-system problem. Common coupling is the reason "globals are evil."

Functional Independence — The combined property of high cohesion + low coupling. A functionally independent module can be developed, tested, modified, and replaced without forcing changes elsewhere. The single most important quality metric in classical structured design.

SOLID Principles — Robert Martin's five OO design principles, the modern restatement of cohesion/coupling for OO systems. Single Responsibility, Open-Closed, Liskov Substitution, Interface Segregation, Dependency Inversion. Memorising these five is mandatory for any modern software engineering interview.

Single Responsibility Principle (SRP)"A class should have only one reason to change." SRP is the OO restatement of high cohesion: a class with multiple responsibilities will be pulled by multiple change pressures.

Open-Closed Principle (OCP)"Software entities should be open for extension but closed for modification." You should be able to add new behaviour by writing new code (a new subclass, a new strategy) without changing existing code. Achieved primarily through polymorphism.

Liskov Substitution Principle (LSP)"Subtypes must be substitutable for their base types." If Square extends Rectangle but breaks code that expected Rectangle behaviour, the design violates LSP. Often the deciding factor for "should this be inheritance or composition?"

Interface Segregation Principle (ISP)"No client should be forced to depend on methods it does not use." Prefer many small, focused interfaces over one large general one. ISP is the OO restatement of low coupling.

Dependency Inversion Principle (DIP)"Depend on abstractions, not concretions." High-level modules should not depend on low-level modules; both should depend on abstractions. DIP is the principle behind dependency injection and is fundamental to testable code.

Architectural Style / Pattern — A high-level template for system structure. Layered (n-tier) stacks layers each using the one below. Client-Server separates service providers from consumers. Pipe-and-Filter chains stream-processing stages. Event-Driven routes around an event bus. Microservices is fine-grained autonomous services. MVC separates data (Model), presentation (View), and control (Controller).

Three-Tier Architecture — A specific layered architecture with presentation tier (UI), application/business tier (logic), and data tier (database). Each tier can be scaled independently and serves as a security and team-ownership boundary. The classical e-commerce layout.

MVC (Model-View-Controller) — A design pattern from Smalltalk (Trygve Reenskaug, 1979) that separates the Model (data and business logic), the View (presentation), and the Controller (input handling and routing). The foundation of most modern web frameworks (Rails, Django, Spring MVC, ASP.NET MVC).

Microservices — An architectural style where the system is composed of small, autonomous services, each owning its data and deployed independently, communicating over network APIs or message buses. Microservices buy independent scaling and faster team velocity at the cost of operational complexity. Amazon, Netflix, Uber, Flipkart all run microservices.

Top-Down vs Bottom-Up Design — Two complementary design strategies. Top-down decomposes the system starting from its overall goal, progressively refining into smaller modules. Bottom-up starts from the utilities and primitives, composing upwards into larger structures. Most real projects use a hybrid (sandwich) strategy — top-down for the architecture, bottom-up for the libraries.

Structured Design — Yourdon & Constantine's 1979 function-oriented design methodology: draw the DFD, identify transform/transaction centres, map to a structure chart of modules, refine each module. Structured design is the classical predecessor of OO design and is still the basis of much regulated/government documentation.

Structure Chart — A tree-shaped diagram showing modules as boxes and calling relationships as arrows, with annotations for the data (data couples) and control flags (control couples) flowing along each call. Structure charts are the output of structured design.

Transform / Transaction Centre — In structured design, the central module that decides what to do with input data. A transform centre transforms input into output (e.g., compile a source file). A transaction centre dispatches input to one of several handlers (e.g., a menu screen choosing between view, edit, delete).

LCOM (Lack of Cohesion of Methods) — A numerical OO cohesion metric: for each pair of methods in a class, count whether they share at least one instance variable; LCOM is the difference between pairs that don't share and pairs that do. Tools (SonarQube, JDepend) report LCOM as a refactoring signal.

---

Study deep

  1. Constantine's law: "A good design has high cohesion and low coupling." This is not just academic — every modern principle (microservices, SOLID, hexagonal architecture, DDD) restates this in new vocabulary.
  1. Functional independence is the practical measure. A module with high cohesion and low coupling has functional independence — it can be developed, tested and changed without touching the rest of the system.
  1. The hierarchy is qualitative. Levels of cohesion and coupling are descriptive, not numeric. The 1.0-to-7.0 ordering is for teaching — in real code there's no precise way to say "this module has 4.2 cohesion." Tools (e.g. LCOM — Lack of Cohesion of Methods) approximate the idea.
  1. OO design transforms the vocabulary. In object orientation, "modules" are classes. The same cohesion/coupling principles apply, plus extra principles:
  • Single Responsibility (SRP) — a class should have one reason to change (cohesion)
  • Open-Closed (OCP) — open for extension, closed for modification
  • Liskov Substitution (LSP) — subtypes substitutable for parents
  • Interface Segregation (ISP) — many small interfaces over one large
  • Dependency Inversion (DIP) — depend on abstractions, not concretions

The five SOLID principles are the OO restatement of cohesion/coupling.

  1. Bad coupling often comes from shortcuts. "Just use a global variable" or "let me access that struct field directly" are tempting in the moment, but each shortcut increases coupling. Future maintenance cost compounds.
PYQ pattern (almost guaranteed): "What is cohesion and coupling? Explain different types of each." — Define both with the "togetherness" framing; table all 7 cohesion + 5 coupling levels with examples; end with "high cohesion + low coupling = good design."