Change PreventersHigh

Parallel Inheritance Hierarchies: What It Costs and How to Fix It

Two class hierarchies that mirror each other, so adding a subclass in one requires adding a corresponding subclass in the other.

Annual Cost$3.5k - $28k
Severity
4/5
CategoryChange Preventers
Detection4 tools

What It Is

Parallel Inheritance Hierarchies is a special case of Shotgun Surgery applied to class hierarchies. When you add a new subclass to one hierarchy, you must add a corresponding subclass to a parallel hierarchy. For example, every new Vehicle subclass requires a new VehicleInsurance subclass with matching logic. The two hierarchies are coupled, but the coupling is enforced only by developer discipline, not by the type system.

Threshold: When adding a subclass to one hierarchy always requires adding a subclass to another, the hierarchies are parallel. If the naming patterns mirror each other (XFoo/XBar paired with YFoo/YBar), the smell is confirmed.

Why It Costs Money

1

Every new type requires creating two (or more) classes in lockstep. Developers who create only one class leave the system in an inconsistent state, and the bug may not surface until the missing partner class is needed at runtime.

2

The coupling between hierarchies is invisible to the compiler. No static analysis catches a missing parallel subclass until runtime, when a factory or lookup fails to find the corresponding class.

3

Maintaining parallel hierarchies doubles the code review and testing surface. Each hierarchy must be tested independently and in combination, and reviewers must verify that both hierarchies are updated consistently.

Specific Cost Mechanisms

  • Missing partner class bugs: runtime failures when the parallel class is not created, costing 4-8 hours each
  • Double development effort: every new type requires 2x the classes, tests, and documentation
  • Synchronisation failures: hierarchies drift apart over time as developers update one but not the other

Estimated Annual Cost

Cost per instance by team size and codebase size. Based on $120,000 average developer salary. See full methodology.

Team SizeSmall (<50k LOC)Medium (50k-200k)Large (200k+)
3 devs$3,500$8,400$16,800
5 devs$5,800$14,000$28,000
10 devs$8,750$21,000$28,000
20 devs$11,600$28,000$28,000

How to Detect It

Specific rules and thresholds for automated detection. See full tool comparison.

SonarQube
squid:S1200

High coupling between parallel class hierarchies

CodeClimate
similar-code

Detects structurally mirrored hierarchies

Manual
Naming convention analysis

Look for parallel naming patterns: FooHandler/FooValidator, BarHandler/BarValidator

IntelliJ IDEA
Structural search

Can be configured to find mirrored class hierarchies

Refactoring Patterns

Proven techniques to eliminate this smell. See all refactoring patterns.

Move Method/Field

One hierarchy can absorb the behaviour of its parallel partner

Effort: 4-12 hours
Impact: Eliminates one entire hierarchy

Merge Hierarchies

The parallel classes have no independent reason to exist

Effort: 8-24 hours
Impact: Reduces class count by 50% and eliminates synchronisation requirement

Replace Inheritance with Delegation

The parallel relationship is better expressed as composition

Effort: 4-8 hours per pair
Impact: Makes the relationship explicit and eliminates the need for lockstep creation

Related Smells