# Modular Decomposition and Reuse

Computer Science I · Programming II · https://tryals.app/learn/computer-science-i/modular-decomposition-and-reuse

## Modular Decomposition

As programs grow, **modular decomposition** splits them into **modules**: self-contained units with a **public interface** (what others use) and **private** internals.

| Principle | Description |
| --- | --- |
| **High Cohesion** | Each module has one clear responsibility. |
| **Low Coupling** | Minimal, well-defined dependencies between modules. |
| **DRY Principle** | Factor shared logic into one place to prevent code drift. |

> **Pitfall:** Copy-pasting logic instead of factoring it creates duplicate copies that inevitably drift apart, causing subtle, inconsistent bugs.

## Reuse by Extension

A module is reused by being called, but **inheritance** offers a second route. A **subclass** inherits fields and methods from a **superclass**, adding or replacing what differs.

- **Polymorphism:** A loop calls a method on a superclass reference, but **dynamic dispatch** runs the actual subclass method at run time.
- **Substitution Principle:** A subclass must genuinely work wherever its superclass is expected.

> **Pitfall:** Reaching for inheritance just to share code. Inheritance creates tight coupling; use **composition** (holding an object as a field) when the true relationship is "has a" or "uses a".

## Practice questions

6 of this lesson's 12 practice questions, with answers. The full set is in the app.

### 1. Two modules each work perfectly and fail when combined. What kind of defect does that suggest, and why do unit tests miss it?

A. A random fault, since two correct modules cannot fail together
B. An interface mismatch, which only an integrated test reveals
C. A compilation error, which unit tests do not check
D. A performance problem that only appears at scale

**Answer:** B. An interface mismatch, which only an integrated test reveals

**Why:** Unit tests check each module against your belief about the other, encoded in a mock, so a mistaken belief is baked into both sides and neither test fails. It is precisely what integration testing exists for, and why contract or consumer-driven tests are used to pin the boundary down explicitly.

Page: https://tryals.app/practice/computer-science-i/modular-decomposition-and-reuse/two-modules-each-work-perfectly-and-fail-when-combined-what-kind-of

### 2. Match each modular-design term to what it describes.

**Answer:**

- Module → A self-contained unit responsible for one coherent part of the job
- Public interface → The part of a module that other modules may use
- DRY principle → The same logic should live in exactly one place
- Parallel development → Separate people work on separate modules, meeting at the interfaces

**Why:** Modules and their public interfaces are the structure; DRY is the rule that decides where logic belongs; parallel development is a benefit that follows once boundaries are agreed. All three of the latter depend on the first: without real module boundaries there is nothing to publish, nowhere single to put logic, and no way to divide work.

Page: https://tryals.app/practice/computer-science-i/modular-decomposition-and-reuse/match-each-modular-design-term-to-what-it-describes

### 3. `SavingsAccount` extends `Account` and overrides `applyMonthly()`. A variable declared as `Account` is holding a `SavingsAccount`. Complete the sentence.

**Answer:** Calling applyMonthly() on that variable runs **SavingsAccount's body, chosen at run time from the object**.

**Why:** Dynamic dispatch selects the body from the object's actual class, so SavingsAccount's version runs even though the variable is declared Account. The declared type governs only which calls are permitted. Choosing on the declared type is the classic error, it would make polymorphism impossible, since the whole point is that one call site serves many classes.

Page: https://tryals.app/practice/computer-science-i/modular-decomposition-and-reuse/savingsaccount-extends-account-and-overrides-applymonthly-a

### 4. A date-handling module is being designed. Sort each item by whether it should be public or private.

**Answer:**

- Public interface: A function that formats a date as a string, A function that reports whether a year is a leap year, A function that adds a number of days to a date
- Private internals: The lookup array of month lengths used internally, A helper that converts a date into a day count since 1970, The scratch buffer the formatter reuses between calls

**Why:** The public interface should be small and stated in terms of dates, not of the machinery that manipulates them: format, leap-year test and date arithmetic. Month-length tables, internal day counts and scratch buffers exist only to make those work, and publishing them would let callers couple to details you wanted to be free to change.

Page: https://tryals.app/practice/computer-science-i/modular-decomposition-and-reuse/a-date-handling-module-is-being-designed-sort-each-item-by-whether

### 5. The same block of validation logic has been copy-pasted into six files. Select every consequence the lesson attributes to this.

A. The six files become impossible to compile separately
B. A bug fixed in one copy remains in the other five
C. The six copies will drift apart over time
D. Any change to the rule must be made in six places
E. The program will run six times more slowly

**Answer:** B. A bug fixed in one copy remains in the other five; C. The six copies will drift apart over time; D. Any change to the rule must be made in six places

**Why:** Duplication multiplies the cost of every change, guarantees the copies eventually disagree, and lets a fix land in one place while the same bug survives elsewhere. It does not slow execution, each file still runs its own copy once, and it does not affect compilation. Reading DRY as a performance rule rather than a maintenance rule is the common misreading.

Page: https://tryals.app/practice/computer-science-i/modular-decomposition-and-reuse/the-same-block-of-validation-logic-has-been-copy-pasted-into-six

### 6. Order the steps of factoring duplicated logic into one reusable unit.

**Answer:**

1. Notice that the same logic appears in several places
2. Compare the copies and identify what actually differs between them
3. Write one function whose parameters cover those differences
4. Replace each copy with a call to that function
5. Change the rule once, in the single remaining definition

**Why:** The differences between copies determine the parameters, so they must be found before the shared function can be written; the call sites are then replaced, and only after that does a change become a one-place edit. Jumping straight to writing the function is how people produce a shared routine that does not actually fit every call site.

Page: https://tryals.app/practice/computer-science-i/modular-decomposition-and-reuse/order-the-steps-of-factoring-duplicated-logic-into-one-reusable-unit
