Das Gesetz der Demeter

oop clean code gesetz demeter

Durch Objektorientierte Programmierung versucht man unter anderem, die einzelnen Komponenten einer Software möglichst lose zu koppeln und Abhängigkeiten zu vermeiden. Ein erster Schritt in diese Richtung ist es, die Eigenschaften eines Objektes als private oder protected zu kennzeichnen. Der Zugriff auf diese Eigenschaften erfolgt ausschließlich über entsprechende set- und get-Methoden. Dadurch haben wir z.B. die Möglichkeit, den Namen der Eigenschaft zu verändern ohne die Änderung an allen Stellen durchführen zu müssen, die die Eigenschaft des Objektes verwenden.

Das hier beschriebene Prinzip nennt sich Kapselung. Schauen wir uns das bei folgendem (sinnfreien) Beispiel an.

class Car
{
    private $_name;

    public function __construct($name)
    {
        $this->_name = $name;
    }

    public function getName()
    {
        return $this->_name;
    }
}

class Person
{
    private $_name;

    private $_car;

    public function __construct($name, Car $car)
    {
        $this->_name = $name;
        $this->_car  = $car;
    }

    public function getName()
    {
        return $this->_name;
    }

    public function getCar()
    {
        return $this->_car;
    }
}

class Logger
{
    public function log(Person $value)
    {
        printf(
            '%s fährt einen %s',
            $value->getName(),
            $value->getCar()->getName()
        );
    }
}

$car    = new Car('VW Golf');
$person = new Person('John', $car);
$logger = new Logger();
$logger->log($person);

Soweit so gut, unsere Daten sind alle ordentlich gekapselt. Was aber, wenn wir nun aus der getName-Methode eine getShortName-Methode machen wollen? Nun stehen wir vor dem gleichen Problem, das wir schon bei der Kapselung hatten. Wir müssen unsere Änderungen unter Umständen an vielen Stellen durchführen. Auch wenn die IDE heutzutage viel Arbeit abnimmt, wir haben eine Menge Abhängigkeiten geschaffen und genau das wollten wir ja eigentlich vermeiden.

Hier kommt uns nun eine griechische Göttin zur Hilfe: Demeter. Das nach ihr benannte Gesetz der Demeter (Englisch Law of Demeter) besagt folgendes:

Objekte sollen nur mit Objekten ihrer unmittelbaren Umgebung kommunizieren. Die Methode M der der Klasse K darf also nur

  • die Methoden von K selbst,
  • die Methoden der an M übergebenen Parameter,
  • die Methoden der innerhalb von M erzeugten Objekten und
  • die Methoden der Eigenschaften von K
  • nutzen.

Unser Beispiel verstößt gegen dieses Gesetz. Die log-Methode nutzt eine Methode der Klasse Car, obwohl dies nach dem Gesetz der Demeter nicht erlaubt ist. Um dies zu verhindern, benötigen wir eine Wrapper-Methode getCarName:

class Person
{
    //...

    public function getCarName()
    {
        return $this->_car->getName();
    }
}

class Logger
{
    public function log(Person $value)
    {
        printf(
            '%s fährt einen %s',
            $value->getName(),
            $value->getCarName()
        );
    }
}

Unsere Logger-Klasse hält sich nun an das Gesetz der Demeter. Der Vorteil ist leicht ersichtlich, wenn wir z.B. feststellen, dass wir von den Autos immer nur einen Namen benötigen, könnten wir die Klasse Car durch einen String ersetzen ohne dass irgendjemand außer der Person-Klasse davon etwas mitbekommen würde:

class Person
{
    private $_name;

    private $_carName;

    public function __construct($name, $carName)
    {
        $this->_name    = $name;
        $this->_carName = $carName;
    }

    public function getName()
    {
        return $this->_name;
    }

    public function getCarName()
    {
        return $this->_carName;
    }
}

Der Nachteil den wir für für die geringe Kopplung hinnehmen müssen, ist eine zusätzliche Wrapper-Methode. Je nach Komplexität können das eine ganze Menge dieser Wrapper-Methoden werden, die gerade für Anfänger der Objektorientierten Programmierung überflüssig wirken.

Fazit: Das Gesetz der Demeter hilft, die Anzahl der Kopplungen zu reduzieren und erhöht so die Wartbarkeit des Systems. Die zusätzlich nötigen Wrapper-Methoden kann man da ruhig in Kauf nehmen.

2 Gedanken zu „Das Gesetz der Demeter“

  1. Hi Oskar,

    schön und sehr anschaulich geschrieben. Stecke gerade in einem Refactoring-Prozess einer Software bei der dieses Gesetz absolut keine Anwendung fand.

    Ich überlege gerade ob es nicht sogar Sinn macht, einen Hinweis auf das „Gesetz der Demeter“ gesondert in die Programmierrichtlinien aufzunehmen …

    Mach weiter so 😉

    Benjamin

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *