Problem Statement
When using inheritance excessively, code becomes rigid and tightly coupled. Changes in a parent class can unexpectedly break child classes, and deep inheritance trees make understanding and modifying behavior difficult.
This diagram shows a composite object containing two separate behavior components, illustrating how composition assembles functionality by combining smaller parts.
### Before: Inheritance (rigid and tightly coupled) class Animal: def speak(self): return "Some sound" class Dog(Animal): def speak(self): return "Bark" class Cat(Animal): def speak(self): return "Meow" ### After: Composition (flexible and reusable) class SpeakBehavior: def speak(self): pass class BarkBehavior(SpeakBehavior): def speak(self): return "Bark" class MeowBehavior(SpeakBehavior): def speak(self): return "Meow" class Animal: def __init__(self, speak_behavior): self.speak_behavior = speak_behavior def speak(self): return self.speak_behavior.speak() # Usage dog = Animal(BarkBehavior()) cat = Animal(MeowBehavior()) print(dog.speak()) # Bark print(cat.speak()) # Meow