liveBook · Manning

Favor composition over inheritance principle

As explained in Object-Oriented Software Design in C++

The Favor Composition over Inheritance Principle recommends using composition instead of inheritance when composition provides more flexible, encapsulated, less complex, and loosely coupled designs.

Favor composition over inheritance when a has-a relationship makes behavior more flexible than an is-a hierarchy. Composition aggregates behavior objects and avoids hardcoding every behavior into subclasses. section 7.3 section 7.6

Composition improves a design by providing:

  • Runtime flexibility: assign behaviors during construction and modify them later. section 7.3
  • Code sharing: reuse behavior classes instead of duplicating subclass implementations. section 7.3
  • Loose coupling and encapsulation: toys need not know how play and sound behaviors are implemented. section 7.3
  • Reduced complexity: simplify class hierarchies without requiring multiple inheritance. section 7.3

Refactoring toy behaviors

A subclass-based toy design hardcodes each toy’s play and sound behavior, causing duplication and change leaks. A composed Toy instead receives PlayAction and Sound objects, delegates play() and sound(), and can change a train’s sound from ChooChoo to Engine at run time. section 7.3

Figure 7.4 Each Toy subclass has an is-a relationship to the Toy superclass. The Toy superclass has has-a relationships to the PlayAction and Sound behaviors, which allows the Toy subclasses to access and share play action and sound behaviors. This design is more flexible and has loose coupling between the toys and their play action and sound behaviors. The toy behaviors are no longer hardcoded in the source code but can be specified whenever a toy object is created at run time. A toy’s behaviors can also be modified at run time by calling the setter functions set_play() and set_sound().

The relationship diagram shows toys retaining inheritance for their identity while composing replaceable play and sound behaviors. section 7.3

How Object-Oriented Software Design in C++ covers it

How deep it goes
Explains tradeoffs through flawed and refactored toy designs, stopping short of broader implementation or ownership guidance.
Examples
Demonstrates Toy objects composed with PlayAction and Sound behaviors, including runtime replacement of a train’s sound.
What it assumes
Assumes object-oriented classes and inheritance, while teaching is-a and has-a relationships through concrete examples.
What you can do after
Apply composition in C++ class designs to share, delegate, assign, and modify object behaviors at run time.
How it connects
Connects composition with inheritance, delegation, aggregation, loose coupling, encapsulation, and the Liskov Substitution Principle.

Also explained in

Compare how 2 books explain favor composition over inheritance principle →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Object-Oriented Software Design in C++. The section links point to the parts of the book it draws on.