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
composition over inheritance in system design?class Battery {
int capacity = 100;
}
class Phone {
Battery battery = new Battery();
int getBatteryCapacity() {
return battery.capacity;
}
}
Phone p = new Phone();
System.out.println(p.getBatteryCapacity());class Screen { }
class Laptop {
Screen screen;
Laptop() {
screen = null;
}
void display() {
System.out.println(screen.toString());
}
}Pass the test and this pattern moves unknown