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".