Das Gesetz von Demeter (englisch Law of Demeter, kurz LoD) ist eine Entwurfsrichtlinie in der objektorientierten Softwareentwicklung. Sie besagt im Wesentlichen, dass Objekte nur mit Objekten in ihrer unmittelbaren Umgebung kommunizieren sollen. Dadurch soll die Kopplung (das heißt die Anzahl von Abhängigkeiten) in einem Softwaresystem verringert und somit die Wartbarkeit erhöht werden. Es wird deswegen manchmal auch als „Prinzip der Verschwiegenheit“ bezeichnet.
Die Richtlinie wurde 1987 an der Northeastern University in Boston vorgeschlagen. Der Name geht auf das Demeter-Projekt zurück, in dem die Richtlinie erstmals erkannt wurde. Dieses Projekt wurde für eine nach dem griechischen Gott Zeus benannte Hardware-Beschreibungssprache entwickelt, weshalb der Name Demeter – in der griechischen Mythologie eine Schwester von Zeus – gewählt wurde. Später erst wurde die Idee beworben, dass Softwareentwicklung mehr mit dem Wachsen von Software (Demeter ist die Göttin der Landwirtschaft) und weniger mit dem Bauen von Software zu tun hat.[1]
Das Gesetz wurde von Karl J. Lieberherr und Ian Holland 1989 im Paper Assuring Good Style for Object-Oriented Programs detailliert erläutert.[2] Durch die formale Spezifikation ist die Verwendung als Softwaremetrik möglich. Es bietet sich somit ein Einsatz des LoD zur Früherkennung von Wartungsproblemen an.
Die Richtlinie kann umgangssprachlich zu der Aussage „Sprich nur zu deinen nächsten Freunden“ zusammengefasst werden. Man spricht in diesem Zusammenhang auch von schüchternem Code. „Schüchterner Code“ schickt so wenige Nachrichten wie möglich an andere Codeteile. Formal ausgedrückt soll eine Methode m einer Klasse K ausschließlich auf folgende Programm-Elemente zugreifen:
Das folgende Beispiel (in Java) verstößt gegen das Demeter-Gesetz, da die Klasse Fahrer
indirekt über die Klasse Auto
auf eine Methode der Klasse Motor
zurückgreift:
class Motor {
public void anlassen() {
// den Motor starten.
}
}
class Auto {
private Motor motor;
public Auto() {
motor = new Motor();
}
public Motor getMotor() {
return motor;
}
}
class Fahrer {
public void fahren() {
Auto zuFahrendesAuto = new Auto();
zuFahrendesAuto.getMotor().anlassen(); //hier wird gegen das Gesetz verstoßen
}
}
Eine Lösung wäre hier, eine Wrapper-Methode in der Klasse Auto
einzuführen, welche den Aufruf an die Klasse Motor
delegiert:
class Motor {
public void anlassen() {
// den Motor starten.
}
}
class Auto {
private Motor motor;
public Auto() {
motor = new Motor();
}
public void fahrbereitmachen() {
motor.anlassen();
}
}
class Fahrer {
public void fahren() {
Auto zuFahrendesAuto = new Auto();
zuFahrendesAuto.fahrbereitmachen();
}
}
Diese Lösung hat den Vorteil, dass nun die fahrbereitmachen
-Methode beliebig modifiziert werden kann, ohne dass der Aufrufer Details darüber kennen muss. Ein Elektroauto ohne Anlasser könnte somit gleichermaßen bedient werden. Die Methode getMotor()
wird dann für diesen Anwendungsfall gar nicht benötigt, ist also erst einmal nicht Teil des Interfaces für ein Auto
.
Bei Anwendung des Gesetzes von Demeter sollte sich durch die geringere Abhängigkeit (Kopplung) der Objekte von der internen Struktur anderer Objekte eine bessere Wartbarkeit, Testbarkeit und Anpassbarkeit der Software (= wesentliche Qualitätskriterien für Software nach ISO/IEC 25000) ergeben.
Andererseits erfordert die Anwendung häufig Vermittler-Methoden (Wrapper), was den initialen Entwicklungsaufwand erhöhen kann, sofern keine automatisierten Werkzeuge zu ihrer Erzeugung eingesetzt werden. Außerdem können Wrapper die Performance geringfügig verschlechtern und den Speicherverbrauch leicht erhöhen.