Upgrade to Pro — share decks privately, control downloads, hide ads and more …

"La tassa sull'ereditarietà" - Composition Over Inheritance

"La tassa sull'ereditarietà" - Composition Over Inheritance

Slides for a talk I gave at the local PHP user group, about some of the differences between inheritance and composition in object oriented software.

Recording: https://www.youtube.com/watch?v=4NJlgX4oTL0

Francesco Mosca

June 29, 2016
Tweet

More Decks by Francesco Mosca

Other Decks in Technology

Transcript

  1. DEFINITIONS TWO COMMON PATHS TO CODE REUSE ▸ Inheritance: a

    class may inherit […] the fields and methods of its superclass. Inheritance is transitive […]. Subclasses may override some methods and/or fields to alter the default behavior. ▸ Composition: when a Field’s type is a class, the field will hold a reference to another object, thus creating an association relationship between them. Steven Lowe - Composition vs. Inheritance: How to Choose?
  2. REMEMBER THIS! “REUSING THE IMPLEMENTATION” “[…] THE NEW PROGRAMMER CAN

    GET THE IDEA THAT INHERITANCE SHOULD BE USED EVERYWHERE. THIS CAN RESULT IN AWKWARD AND OVERLY COMPLICATED DESIGNS. INSTEAD, YOU SHOULD FIRST LOOK TO COMPOSITION WHEN CREATING NEW CLASSES, SINCE IT IS SIMPLER AND MORE FLEXIBLE.” (Bruce Eckel - Thinking In Java, 1998) “FAVORING OBJECT COMPOSITION OVER CLASS INHERITANCE HELPS YOU KEEP EACH CLASS ENCAPSULATED AND FOCUSED ON ONE TASK. YOUR CLASSES AND CLASS HIERARCHIES WILL REMAIN SMALL AND WILL BE LESS LIKELY TO GROW INTO UNMANAGEABLE MONSTERS. “ (Gamma et al - Design Patterns, 1994)
  3. YEAH, SURE… Bruce Eckel - Thinking In Java “YOU CREATE

    A BASE TYPE TO REPRESENT THE CORE OF YOUR IDEAS ABOUT SOME OBJECTS IN YOUR SYSTEM. FROM THE BASE TYPE, YOU DERIVE OTHER TYPES TO EXPRESS THE DIFFERENT WAYS THAT THIS CORE CAN BE REALIZED.“ BUT THEN… (continues for 8 pages)
  4. A STOLEN EXAMPLE SO, WHAT’S THE (FIRST) PROBLEM? Mattias Petter

    Johansson - Composition over Inheritance bark() poop() Dog meow() poop() Cat
  5. A STOLEN EXAMPLE SO, WHAT’S THE (FIRST) PROBLEM? Mattias Petter

    Johansson - Composition over Inheritance bark() Dog meow() Cat poop() Animal
  6. A STOLEN EXAMPLE SO, WHAT’S THE (FIRST) PROBLEM? Mattias Petter

    Johansson - Composition over Inheritance clean() CleanerRobot kill() MurderRobot drive() Robot
  7. A STOLEN EXAMPLE SO, WHAT’S THE (FIRST) PROBLEM? Mattias Petter

    Johansson - Composition over Inheritance “Our customers demand a MurderRobotDog. It needs to be able to .kill(), .drive(), .bark(), but it cannot poop().
  8. A STOLEN EXAMPLE SO, WHAT’S THE WRONG SOLUTION? Mattias Petter

    Johansson - Composition over Inheritance Dog meow() Cat poop() Animal clean() CleanerRobot kill() MurderRobot drive() Robot bark() GameObject MurderRobot Dog
  9. A STOLEN EXAMPLE SO, WHAT’S ANOTHER WRONG SOLUTION? Mattias Petter

    Johansson - Composition over Inheritance bark() Dog meow() Cat poop() Animal clean() CleanerRobot kill() MurderRobot drive() Robot bark() MurderRobot Dog
  10. A STOLEN EXAMPLE SOOO, WHAT’S THE “RIGHT” SOLUTION? Mattias Petter

    Johansson - Composition over Inheritance poop() Pooper bark() Barker Dog drive() Driver kill() Murderer MurderRobot MurderRobot Dog Cat meow() Meower clean() Cleaner CleanerRobot
  11. ANOTHER STOLEN EXAMPLE BUT, WHAT’S ANOTHER PROBLEM? Chris Hanson, ⚠

    www.hautelooktech.com play() { “thru speakers!” } stop() MusicPlayer changeSide() RecordPlayer muteTrack() EightTrackPlayer
  12. ANOTHER STOLEN EXAMPLE BUT, WHAT’S ANOTHER PROBLEM? Chris Hanson, ⚠

    www.hautelooktech.com play() { “thru headphones!” } eject() Walkman play() { “thru speakers!” } stop() MusicPlayer
  13. ANOTHER STOLEN EXAMPLE BUT, WHAT’S ANOTHER PROBLEM? Chris Hanson, ⚠

    www.hautelooktech.com play() { “thru headphones!” } upload() MP3Player play() { “thru headphones!” } eject() Walkman X
  14. ANOTHER STOLEN EXAMPLE OK THEN, WHAT’S THE “RIGHT” SOLUTION, AGAIN?

    Chris Hanson, ⚠ www.hautelooktech.com play() { “thru headphones!” } HeadphonesOutput play() { “thru speakers!” } SpeakersOutput upload() MP3Player changeSide() RecordPlayer muteTrack() EightTrackPlayer eject() Walkman play() { “thru wathever!” } BluetoothOutput
  15. COMPOSE OR INHERIT? IS-A VS. HAS-A * no animals were

    harmed during the production of these slides (yes, the cat was already dead)
  16. LISKOV SUBSTITUTION PRINCIPLE area() width height Rectangle width height Square

    class  Rectangle  {
    function  area()  {  return  $this-­‐>width  *  $this-­‐>height  }
 
    //  …
 } class  Square  extends  Rectangle  {
 
    function  setWidth($width)  {  
        $this-­‐>width  =  $width;
        $this-­‐>height  =  $width;
    }
 
    //  …
 } function  testArea(Rectangle  $r)  {  
    $r-­‐>width  =  5;
    $r-­‐>height  =  4;
 
    assertEquals(20,  $r-­‐>area());  //  EPIC  FAIL
 }
  17. TRADEOFFS, TRADEOFFS EVERYWHERE… PROS & CONS! ▸ Inheritance specifies the

    Domain in terms of semantics (focus on “what it is”) ▸ Composition allows the Domain to be flexible in terms of behaviors (focus on “what it does”) ▸ Inheritance is good for fixed, well-specified hierarchies (UI), but forces design early on ▸ Composition helps with “the same, but different” (business reqs.) and allows for supple design ▸ Inheritance is easy to (involuntarily) abuse, mixing different concerns and coupling unrelated behaviors, becoming harder to reason about (and test) ▸ Composition is more explicit and, focusing on small and single-responsibility objects, remains easier to reason about (and test) (So yeah, not many tradeoffs: composition is almost always preferable)