Why Composition is Immune to Fragile Base Class Problem
To understand the fragile base class problem and why it doesn’t apply to composition, first you have to understand how it happens:
- A is the base class
- B inherits from A
- C inherits from B
- D inherits from B
C calls `super`, which runs code in B. B calls `super` which runs code in A.
A and B contain unrelated features needed by both C & D. D is a new use case, and needs slightly different behavior in A’s init code than C needs. So the newbie dev goes and tweaks A’s init code. C breaks because it depends on the existing behavior, and D starts working.
What we have here are features spread out between A and B that C and D need to use in various ways. C and D don’t use every feature of A and B… they just want to inherit some stuff that’s already defined in A and B. But by inheriting and calling `super`, you don’t get to be selective about what you inherit. You inherit everything:
“…the problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.” ~ Joe Armstrong
Imagine you have features instead of classes:
feat1, feat2, feat3, feat4
C needs feat1 and feat3, D needs feat1, feat2, feat4:
const c = compose(feat1, feat3);
const d = compose(feat1, feat2, feat4);
Now, imagine you discover that d needs slightly different behavior from feat1. It doesn’t actually need to change feat1, instead, you can make a customized version of feat1 and use that, instead. You can still inherit the existing behaviors from feat2 and feat4 with no changes:
const d = compose(custom1, feat2, feat4);
And c remains unaffected.
The reason this is not possible with class inheritance is because when you use class inheritance, you buy into the whole existing class taxonomy.
If you want to adapt a little for a new use-case, you either end up duplicating parts of the existing taxonomy (the “duplication by necessity problem”), or you refactor everything that depends on the existing taxonomy to adapt the taxonomy to the new use case due to the fragile base class problem.
Composition is immune to both.