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)
  • Separation
  • Coupling
  • Duplication of effort
  • Comparison

    • Related Antipatterns: None directly.
    • Related Principles: High Coupling.

    Code example

    Typescript

    Bad (The Antipattern)

    Good (The Fix)