Parallel Inheritance Hierarchies
Subclassing one thing forces subclassing another.
“Every time you make a subclass of one class, you also have to make a subclass of another.” – Fowler & Beck
Signs of Use (Symptoms)
- Prefixes match across hierarchies (e.g.,
DomesticOrder,DomesticShipping,DomesticTax). - Modifying one hierarchy is always paired with modifying another.
Why it is bad (Consequences)
- Coupling: Two hierarchies are tightly coupled.
- Tedious: Double the work for every new type.
Why it happens (Root Cause)
Inheritance was overused. Two related concepts were abstracted into their own hierarchy.
When it might be okay (Exceptions)
- Rarely.
Explanation
Problem
You have Order -> DomesticOrder, InternationalOrder. And Shipping -> DomesticShipping, InternationalShipping. Every new order type requires a new shipping type.
The Flaw
Parallel structures that must stay in sync.
Real world analogy
Having a separate “Driver’s License” card for every car you own, instead of one generic license that works for all.
Refactoring Solution
- Move Method / Move Field: Merge the hierarchies or delegate.
- Replace Inheritance with Delegation.
Pros and Cons (of the Antipattern)
| Pros (Why people do it) | Cons (The price you pay) |
|---|---|
Comparison
- Related Antipatterns: None directly.
- Related Principles: High Coupling.
Code example
Typescript
Bad (The Antipattern)
Good (The Fix)