principlepythonModeratepending
Principle: Composition over inheritance
Viewed 0 times
compositioninheritancecouplingflexibilitydesign
Problem
Deep inheritance hierarchies are rigid, hard to understand, and create tight coupling. Changes to base classes ripple through all subclasses.
Solution
Prefer composing behavior from small, focused components over inheriting from base classes:
# BAD: Deep inheritance
class Animal:
def move(self): ...
class Bird(Animal):
def fly(self): ...
class Penguin(Bird): # Penguins can't fly!
def fly(self): raise NotImplementedError # Violation of LSP
# GOOD: Composition
class Animal:
def __init__(self, movement, sound):
self.movement = movement
self.sound = sound
class FlyMovement:
def move(self): return 'flying'
class WalkMovement:
def move(self): return 'walking'
class SwimMovement:
def move(self): return 'swimming'
bird = Animal(FlyMovement(), ChirpSound())
penguin = Animal(SwimMovement(), HonkSound())
Guidelines:
# BAD: Deep inheritance
class Animal:
def move(self): ...
class Bird(Animal):
def fly(self): ...
class Penguin(Bird): # Penguins can't fly!
def fly(self): raise NotImplementedError # Violation of LSP
# GOOD: Composition
class Animal:
def __init__(self, movement, sound):
self.movement = movement
self.sound = sound
class FlyMovement:
def move(self): return 'flying'
class WalkMovement:
def move(self): return 'walking'
class SwimMovement:
def move(self): return 'swimming'
bird = Animal(FlyMovement(), ChirpSound())
penguin = Animal(SwimMovement(), HonkSound())
Guidelines:
- Inherit for 'is-a' relationships that are truly stable
- Compose for 'has-a' or 'can-do' relationships
- Limit inheritance depth to 2-3 levels max
- Prefer interfaces/protocols over abstract base classes
Why
Composition gives you flexibility to mix and match behaviors without the constraints of a rigid class hierarchy.
Revisions (0)
No revisions yet.