IT-Berufe-Podcast

Liskov Substitution Principle (LSP) – Wissenshäppchen #5


Listen Later

Im fünften Wissenshäppchen geht es um das Liskov Substitution Principle.

Inhalt

Das LSP ist das dritte der fünf SOLID-Prinzipien. Es wurde 1987 von Barbara Liskov definiert, die ihm auch seinen Namen gab:

Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.

Man könnte sagen, dass dies quasi die Grundanforderung ist, um Polymorphie zu ermöglichen. Denn überall dort, wo eine Basisklasse oder ein Interface erwartet wird, müssen auch alle abgeleiteten bzw. implementierenden Klassen erlaubt sein. Dies ist in den heutigen Programmiersprachen auch der Fall und der Compiler prüft dies (statisch). Aber das LSP geht noch einen Schritt weiter und fordert auch zur Laufzeit ein korrektes Verhalten.

Erklärung
  • Subklassen müssen sich so verhalten, wie es von ihren Basisklassen erwartet wird. Dies gilt auch für Interfaces und ihre Implementierungen.
  • Statisch ist das kein Problem: Der Compiler prüft, ob alle geforderten Methoden von den Subklassen bzw. implementierenden Klassen angeboten werden.
  • Die korrekte Verhaltensweise der Implementierung in den Subklassen bzw. implementierenden Klassen kann jedoch nicht statisch geprüft werden. Hierfür ist der Entwickler zuständig, um das LSP nicht zu verletzen.
  • Wenn beispielsweise eine Subklasse in einer überschriebenen Methode eine NotImplementedException wirft, anstatt sie zu implementieren, wird das LSP verletzt.
  • Aber auch unerwartete Nebeneffekte der Implementierungen in überschriebenen Methoden verletzten das LSP (Beispiel: Square erbt von Rectangle und setzt beim Aufruf von setA() auch die Seite b auf den gleichen Wert).
  • Beispiel

    Die Basisklasse Employee gibt die Methode work_overtime() vor, die damit in allen Subklassen (Manager und Developer) zur Verfügung steht. Somit kann das Project gerade noch erfolgreich fertiggestellt werden.

    class Employee
    def work_overtime
    puts "Working in the evening and on weekends..."
    end
    end
    class Manager < Employee
    end
    class Developer < Employee
    end
    class Project
    def finish(employees)
    employees.each { |e| e.work_overtime }
    "Project done"
    end
    end
    puts Project.new.finish([Manager.new, Developer.new])
    # Working in the evening and on weekends...
    # Working in the evening and on weekends...
    # Project done

    Aber was passiert, wenn sich der Developer zwar formell an den „Vertrag“ seiner Basisklasse hält, die Methode work_overtime() aber wie folgt überschreibt?

    class Developer < Employee
    def work_overtime
    raise "Sorry, I use XP and adhere to the 40 hour workweek"
    end
    end
    puts Project.new.finish([Manager.new, Developer.new])
    # Working in the evening and on weekends...
    # Traceback (most recent call last):
    # 4: from ./LSP.rb:23:in `'
    # 3: from ./LSP.rb:18:in `finish'
    # 2: from ./LSP.rb:18:in `each'
    # 1: from ./LSP.rb:18:in `block in finish'
    # ./LSP.rb:12:in `work_overtime': Sorry, I use XP and adhere to the 40 hour workweek (RuntimeError)

    Autsch! Das Project ist wohl zum Scheitern verurteilt! 😉 Es hatte ja keine Ahnung, dass man Developer nicht zu Überstunden verdonnern kann, denn das geht ja schließlich bei allen Employees…

    Vorteile
    • Der Code wird deutlich besser nachvollziehbar, da keine unerwarteten Fehler zur Laufzeit auftreten, obwohl laut Compiler alles ok ist.
    • Klassen verhalten sich so, wie man es von ihnen erwarten würde („Principle of Least Astonishment“), und überraschen den Entwickler nicht.
    • Nachteile
      • Die Möglichkeiten der Vererbung werden ein wenig eingeschränkt.
      • Literaturempfehlungen

        Auch beim dritten SOLID-Prinzip empfehle ich wieder Uncle Bobs Clean Code*.

        *

        Links
        • Permalink zu dieser Podcast-Episode
        • RSS-Feed des Podcasts
        • Liskov Substitution Principle
        • ArticleS.UncleBob.PrinciplesOfOod (Artikel von Uncle Bob, Beispiel in C++)
        • Liskovsches Substitutionsprinzip – Wikipedia
        • ...more
          View all episodesView all episodes
          Download on the App Store

          IT-Berufe-PodcastBy Stefan Macke

          • 5
          • 5
          • 5
          • 5
          • 5

          5

          1 ratings


          More shows like IT-Berufe-Podcast

          View all
          Streitkräfte und Strategien by NDR Info

          Streitkräfte und Strategien

          45 Listeners

          Sternengeschichten by Florian Freistetter

          Sternengeschichten

          45 Listeners

          Geschichten aus der Geschichte by Richard Hemmer und Daniel Meßner

          Geschichten aus der Geschichte

          199 Listeners

          c’t uplink - der IT-Podcast aus Nerdistan by c’t Magazin

          c’t uplink - der IT-Podcast aus Nerdistan

          6 Listeners

          MORD AUF EX by Leonie Bartsch & Linn Schütze

          MORD AUF EX

          123 Listeners

          {ungeskriptet} - Gespräche, die dich weiter bringen by Ben Berndt

          {ungeskriptet} - Gespräche, die dich weiter bringen

          26 Listeners