Favor composition when a has-a relationship makes behavior more flexible than an is-a hierarchy. Composed objects avoid hardcoding behavior, reduce duplication, and remain loosely coupled. section 7.3.3
Toy behaviors
A Toy receives PlayAction and Sound objects through its constructor. ToyCar, ModelAirplane, and TrainSet can therefore share or vary behaviors, and a train can change its sound at runtime. section 7.3.3
Composition provides:
- Flexibility: assign or modify behaviors at runtime. section 7.3.3
- Code sharing and delegation without duplicating behavior across subclasses. section 7.3.3
- Loose coupling, encapsulation, simpler hierarchies, and no need for multiple inheritance. section 7.3.3
Listing 7.21 (Program 7.10 Toys-3): playaction.py (has-a relationships)
from abc import ABC, abstractmethod
class PlayAction(ABC):
@staticmethod
@abstractmethod
def play(self): pass
class RollPlay(PlayAction):
@staticmethod
def play(): return 'roll it'
class FlyPlay(PlayAction):
@staticmethod
def play(): return 'fly it'
Shows interchangeable PlayAction implementations used as composed behaviors. section 7.3.3

