# Law of Demeter ## Einführung Das Law of Demeter (deutsch *Gesetz von Demeter*) Prinzip ist eine Entwurfs-Richtlinie in der Objektorientierten Programmierung und beschreibt das Prinzip des wenigsten Wissens (*principle of least knowledge*). > Benannt wurde das Prinzip nach der griechischen Göttin wegen der Verwandschaft zum Projekt Zeus (Der Bruder von Demeter). Einfach zusammengefasst sollten folgende Regeln beachtet werden: 1. Jede Einheit sollte nur wenig über andere Einheiten wissen. 2. Jede Einheit sollte nur mit Freunden kommunizieren, nicht mit Fremden. 3. Einheiten sollten nur mit ihren direkten Freunden kommunizieren So sollte jedes Objekt nur möglichst wenig über die Struktur und Eigenschaften von anderen Objekten kennen wie unbedingt nötig.[^1] Genau gesagt sollte eine Methode M in einer Klasse C nur auf Objekte zugreifen, wenn sie: - Instanz Variablen von C sind - Argument Klassen von M sind - Instanzen, die innerhalb von M erstellt werden sind - Eine direkte Eigenschaft von C sind [^2] ## Beispiel ```CSharp public class Motor { public void Start() { // Motor anschalten } } public class Auto { public Motor Motor { get; set; } public Auto() { Motor = new Motor(); } } public class Main { public static void Main() { Auto auto = new Auto(); auto.Motor.Start(); } } ``` In diesem Beispiel haben wir einen klaren Verstoss gegen das Gesetz von Demeter. In Main haben wir ein Objekt von Auto, welches über dessen Eigenschaft Motor gestartet wird. Motor ist für Main fremd und durch die Verkettung entstehen viele Abhängigkeiten. Es gibt zwei Wege diesen Code aufzuräumen: ### Aufteilung ```CSharp public static void Main() { Auto auto = new Auto(); Motor autoMotor = auto.Motor; autoMotor.Start(); } ``` Durch die Extrahierung des Motors in ein eigenes Objekt ist es nicht mehr fremd und es wäre kein Verstoss mehr. Es bestehen jedoch immer noch die gleiche Anzahl an Abhängigkeiten. Der empfohlene Weg ist also einen Wrapper zu verwenden. ### Wrapper ```CSharp public class Auto { private Motor motor; public Auto() { motor = new Motor(); } public void Start() { motor.Start(); } } public class Main { public static void Main() { Auto auto = new Auto(); auto.Start(); } } ``` Durch die Einbindung einer Wrappermethode für den Start des Autos reduzieren wir die Abhängigkeit, da Main nicht mehr auf den Motor zugreifen muss. Ändert sich nun etwas an der Implementation von Auto oder Motor, müssen nur noch diese beiden Klassen beachtet werden. ## Warum sollte man sich daran halten Eine Studie von Guo et al., 2011[^2] zeigt eine direkte Korrelation von Anzahl an Verstossen gegen das Gesetz und Bugs. So hat sich auch gezeigt, dass Verstosse als früher Indikator für Fehleranfälligkeit genutzt werden können. [^1]: https://en.wikipedia.org/wiki/Law_of_Demeter [^2]: https://www.khoury.northeastern.edu/home/lieber/LoD/LoD-2011-Zurich.pdf