IT-Berufe-Podcast

Law of Demeter (LoD) – Wissenshäppchen #8


Listen Later

Law of Demeter (LoD)

Um das Law of Demeter (Gesetz von Demeter) in der Softwareentwicklung geht es im achten Wissenshäppchen.

Inhalt

Das Law of Demeter sagt aus, dass eine Methode nur Zugriff auf die folgenden Objekte/Methoden haben sollte:

  • Andere Instanzmethoden in ihrer eigenen Klasse
  • Ihre Parameter
  • Methoden in Objekten, die sie selbst erzeugt
  • Globale Variablen
  • Eine einfache andere Definition lautet: Verkette keine Methodenaufrufe („method chaining“). Oder: Verwende nicht mehr als einen ., wenn du auf etwas zugreifst. Ein anderer Name für das LoD ist „Prinzip des geringsten Wissens“ („principle of least knowledge“).

    Der Name stammt von Demeter, einer griechischen Göttin. Der „Erfinder“ des Prinzips entwickelte in den 80er-Jahren ein System mit diesem Namen.

    Erklärung
    • Vorweg: Globale Variablen waren in den 80ern hip, heute nicht mehr. Bitte verwende sie am besten gar nicht.
    • Je mehr „Punkte“ in einer Aufrufhierarchie auftreten, desto mehr Kenntnis hat eine Komponente vom „Innenleben“ der aufgerufenen Komponenten.
    • Je mehr Kenntnis eine Komponente über die von ihr verwendeten Komponenten hat, desto stärker bindet sie sich an diese. Wenn sich die genutzten Komponenten ändern, muss sie sich mit ändern bzw. ist kaputt.
    • Das verletzt das Geheimnisprinzip und die Kapselung, nach der wir eigentlich in der Objektorientierung arbeiten wollen.
    • Je mehr solcher Abhängigkeiten eine Methode hat, desto schwerer ist sie zu verstehen und zu testen.
    • Code, der sich an das LoD hält, gilt auch als „schüchtern“, weil er „nur mit seinen Freunden spricht“.
    • Beispielcode

      Um an den Gesamtbeitrag einer Versicherungspolice zu kommen, ist die Kenntnis über die darin enthaltenen versicherten Personen und deren Tarife nötig. Da es sich dabei jeweils um Listen handelt, ist sogar noch ein „Flachklopfen“ der Strukturen nötig. Der Code sieht vielleicht cool aus, ist aber stark an die Strukturen gekoppelt. Das heißt, ein Test müsste sehr viel Aufwand betreiben, um die nötigen Strukturen zu schaffen (z.B. mit Mocks).

      class Tarif
      def initialize(name)
      @name = name
      end
      def beitrag
      123.45
      end
      end
      class VersichertePerson
      def initialize(name)
      @name = name
      @tarife = [ Tarif.new("KFZ"), Tarif.new("Hausrat") ]
      end
      def tarife
      @tarife
      end
      end
      class Versicherungspolice
      def initialize
      @versicherte_personen = [ VersichertePerson.new("Stefan Macke"), VersichertePerson.new("Klaus Meyer") ]
      end
      def versicherte_personen
      @versicherte_personen
      end
      end
      # cool, aber schwer verständlich, anfällig für Anpassungen und auch schwer zu testen
      puts Versicherungspolice.new
      .versicherte_personen
      .flat_map { |vp| vp.tarife }
      .inject(0){|summe,tarif| summe + tarif.beitrag }

      Um dies zu vermeiden, können die einzelnen Klassen von ihren inneren Strukturen abstrahieren und stellen simple Zugriffsmethoden für die gewünschten Ergebnisse bereit. Der finale Aufruf sieht nun schon fast langweilig aus. Dafür liegt die fachliche Berechnungslogik da wo sie hingehört: in den jeweiligen Klassen und nicht beim Aufrufer.

      class Tarif
      def initialize(name)
      @name = name
      end
      def beitrag
      123.45
      end
      end
      class VersichertePerson
      def initialize(name)
      @name = name
      @tarife = [ Tarif.new("KFZ"), Tarif.new("Hausrat") ]
      end
      def beitragssumme
      @tarife.inject(0){|summe,tarif| summe + tarif.beitrag }
      end
      end
      class Versicherungspolice
      def initialize
      @versicherte_personen = [ VersichertePerson.new("Stefan Macke"), VersichertePerson.new("Klaus Meyer") ]
      end
      def gesamtbeitrag
      @versicherte_personen.inject(0){|summe,vp| summe + vp.beitragssumme }
      end
      end
      # langweilig, aber einfach zu verstehen und zu testen
      puts Versicherungspolice.new.gesamtbeitrag
      Vorteile
      • Der Code wird verständlicher, weil nicht mehrere Strukturen bekannt sein müssen.
      • Fachliche Logik landet evtl. eher da, wo sie hingehört. Anstatt externen Komponenten Zugriff auf die inneren Daten zu geben, werden Abstraktionen geschaffen.
      • Die Komponenten sind unabhängiger voneinander und lassen sich leichter testen.
      • Große Test-Setups mit vielen Mocks, die weitere Mocks zurückgeben, lassen sich vermeiden.
      • Interne Änderungen an verwendeten Komponenten wirken sich nicht auf deinen Code aus. Du hast also weniger Anpassungsaufwand.
      • Nachteile
        • Wenn du die Regel exakt befolgen möchtest, musst du womöglich recht viel Boilerplate-Code schreiben, z.B. simple Getter, die an Instanzvariablen delegieren.
        • Wenn sich die verwendeten Strukturen selten ändern, ist der zusätzliche Aufwand vermutlich unnötig.
        • Literaturempfehlungen

          Zu diesem Wissenshäppchen gibt es ein separates Kapitel in einem meiner absoluten Lieblingsbücher zur Softwareentwicklung: The Pragmatic Programmer*. Es ist vor Kurzem in der 20-Jahre-Edition neu aufgelegt worden, aber das Law of Demeter ist immer noch Thema.

          *

          Links
          • Permalink zu dieser Podcast-Episode
          • RSS-Feed des Podcasts
          • Gesetz von Demeter – Wikipedia
          • Law Of Demeter
          • Demeter’s Law: Don’t talk to strangers!
          • ...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

            46 Listeners

            Sternengeschichten by Florian Freistetter

            Sternengeschichten

            46 Listeners

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

            Geschichten aus der Geschichte

            186 Listeners

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

            c’t uplink - der IT-Podcast aus Nerdistan

            10 Listeners

            MORD AUF EX by Leonie Bartsch & Linn Schütze

            MORD AUF EX

            122 Listeners

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

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

            29 Listeners