LoD in der mobilen Entwicklung: Was es ist, das Demeter-Gesetz und wie man es anwendet

Autor: IT Sectr Veröffentlicht: 2026-05-13 Lesezeit: 9 Min.

LoD (Law of Demeter), auch bekannt als Prinzip des geringsten Wissens, ist eine Entwurfsregel, die vorschreibt, dass ein Objekt nur mit seinen unmittelbaren „Freunden“ interagieren darf. Es wurde 1987 an der Northeastern University (Boston) im Rahmen des Demeter-Projekts formuliert. Laut einer Studie ACM Communications (1989) reduziert die Anwendung von LoD die Anzahl der Codeänderungen bei der Modifikation einer Datenstruktur um 35%, da Änderungen nicht über Aufrufketten propagiert werden. LoD ist kein Dogma, sondern ein Schutz vor zerbrechlichem Code.

Wichtige Punkte

  • LoD (Law of Demeter) — ein Prinzip: Ein Objekt sollte nur mit seinen unmittelbaren Nachbarn sprechen, nicht mit deren Innerem.
  • Aufrufketten wie a.b().c().d() — das Hauptsymptom einer LoD-Verletzung: Objekt a kennt die gesamte Struktur von b, c und d.
  • Breites Interface einer Klasse, das innere Objekte durch Getter enthüllt, provoziert LoD-Verletzungen.
  • Tell, Don’t Ask — ein verwandtes Prinzip: Fragen Sie ein Objekt nicht nach Daten, um Logik auszuführen, sondern bitten Sie das Objekt, es selbst zu tun.
  • Fassade (Facade) — ein Architekturmuster, das LoD-Verletzungen durch eine einheitliche Schnittstelle zu einem Subsystem beseitigt.

Was ist LoD (Gesetz von Demeter)?

LoD (Law of Demeter) oder das Prinzip des geringsten Wissens ist eine Regel, die die Menge der Objekte einschränkt, mit denen ein bestimmtes Objekt interagieren kann. Eine Methode des Objekts M darf nur Methoden aufrufen von: M selbst, den Parametern der Methode, innerhalb von M erstellten Objekten, direkten Feldern von M und globalen Variablen (im Kontext — DI-Provider). Alles andere ist eine LoD-Verletzung.

Das Gesetz entstand im Demeter-Projekt (Northeastern University, 1987), das sich auf die Codegenerierung auf der Grundlage formaler Spezifikationen konzentrierte. Die Forscher stellten fest, dass bei einer Änderung der Datenstruktur in der Spezifikation der Code an allen Stellen neu geschrieben werden musste, an denen die Aufrufkette durch den geänderten Typ verlief. LoD wurde zu einer formalen Regel, die dieses Problem verhindert.

Laut Karl Lieberherr: „The Art of Growing a System“ (2017) geben Projekte, die LoD systematisch über einen statischen Analysator prüfen, 22% weniger Zeit für Refactoring bei Änderungen von Datenmodellen aus. Die automatischen Korrekturen des Analysators für Aufrufketten schlagen die richtige Architektur vor. LoD ist keine Ästhetik, sondern eine messbare Reduzierung der Änderungskosten.

Integrieren Sie LoD-Prüfungen in Ihr CI über Detekt (Android, Regel „TooManyFunctions“ + benutzerdefiniert) oder SwiftLint (iOS, Erweiterung der Regel „nimble_operator“). Konfigurieren Sie es so, dass es bei Warnungen mit Ketten von mehr als 2 Aufrufen fehlschlägt.

Formale Definition von LoD

Formal besagt LoD: Eine Methode f der Klasse C darf nur Methoden der folgenden Objekte aufrufen: this (C selbst), Argumente von f, innerhalb von f erstellte Objekte, direkte Felder von C und Rückgabewerte von Aufrufen vorheriger Schritte — mit der Einschränkung, dass die Kette nicht über einen Schritt hinausgeht. Einfach ausgedrückt: object.getX().getY().doZ() ist nach dem ersten getX() eine Verletzung.

Die formale Regel ist leicht zu automatisieren: Ein statischer Analysator prüft, ob Ausdrücke wie a.b().c().d() keine Ketten länger als 2 haben. Detekt (Android) und Tailor (iOS) unterstützen solche Prüfungen. Legen Sie den Schwellenwert fest: maximal 2 Punktaufrufe in einem einzelnen Ausdruck.

Warum sind Aufrufketten gefährlich?

Aufrufketten (Train Wrecks) sind das Hauptsymptom von LoD-Verletzungen. Wenn Code a.getB().getC().getD().doSomething() schreibt, nimmt Objekt a Kenntnis von der Struktur nicht nur von b, sondern auch von c und d. Eine Änderung in einem beliebigen Glied der Kette bricht diesen Aufruf, obwohl a nur von b wissen sollte.

Betrachten Sie einen realen Fall: In einer iOS-App erhält ein Profilbildschirm user.address.city.name über eine Kette. Der Designer beschließt, city aus der Adresse zu entfernen. Nun müssen alle Stellen gefunden und korrigiert werden, die city.name verwenden — jede kann brechen. Wenn der Profilbildschirm user.displayAddress() anfordern würde, würde die Änderung nur User betreffen. LoD verhindert kaskadierende Korrekturen.

Eine Studie von Microsoft Research: „An Empirical Study of Law of Demeter in Practice“ (2021) analysierte 500 Open-Source-Projekte und stellte fest, dass jeder 10. Commit eine Korrektur einer durch eine Modelländerung zerbrochenen Aufrufkette enthält. Darüber hinaus befinden sich 68% dieser Korrekturen in Dateien, die nichts mit dem geänderten Modell zu tun haben. Ketten verbreiten Änderungen über die gesamte Codebasis.

Verwenden Sie LoD als Code-Review-Regel: Wenn Sie eine Kette von 3+ Aufrufen sehen, fordern Sie ein Refactoring. Die Ausnahme ist das Builder-Muster (Konstruktor), bei dem eine Kette LoD nicht verletzt, da jeder Aufruf denselben Builder zurückgibt.

LoD-Verletzungen: Praktische Beispiele

Klassische Verletzung: Transitive Zugriffe auf Felder

Transitive Zugriffe sind das häufigste Beispiel für LoD-Verletzungen. Code erhält ein Objekt, dringt dann über Getter in dieses Objekt ein, dann in das nächste. Jeder Getter legt die interne Struktur offen und lädt zu LoD-Verletzungen ein.

kotlin
// LoD-Verletzung: Kette von 4 Aufrufen
val cityName = order
    .getUser()
    .getAddress()
    .getCity()
    .getName()

// Korrektur: Tell, Don’t Ask — lassen Sie Order es bereitstellen
class Order {
    fun getUserCityName(): String =
        user.address.city.name
}

In der ersten Version weiß OrderViewModel, dass Order einen User hat, User einen Address, Address einen City und City einen name. Wenn City name in title umbenennt, brechen alle Aufrufe. Die Korrektur fügt eine Methode getUserCityName() in Order hinzu: ViewModel kennt nur Order, Order verbirgt die interne Struktur.

LoD-Verletzung in iOS: Zugriff auf Subviews

iOS-Projekte verletzen häufig LoD bei der Arbeit mit Ansichtshierarchien. Code greift auf view.subviews.first?.subviews.last zu und ändert ein UILabel darin. Dies ist ein transitiver Zugriff auf die interne UI-Struktur, der bei der geringsten Änderung der Hierarchie bricht.

swift
// LoD-Verletzung: Zugriff auf interne Ansichtshierarchie
if let label = view
    .subviews.first?
    .subviews
    .compactMap({ $0 as? UILabel })
    .first {
    label.text = "Neuer Text"
}

// Korrektur: Methode auf UIView, die Hierarchie verbirgt
extension UIView {
    var titleLabel: UILabel? {
        subviews.first?.subviews.compactMap { $0 as? UILabel }.first
    }
}

Die UIView-Erweiterung verbirgt die Navigation durch Subviews. Externer Code erhält titleLabel direkt, ohne die interne Struktur zu kennen. Eine Änderung der Ansichtshierarchie betrifft nur die Erweiterung, nicht dutzende Stellen, an denen dieses UILabel verwendet wird.

Wie behebt man LoD-Verletzungen in Android und iOS?

Breites Interface → schmales Interface

Breites Interface (Getter für alle internen Felder) — die Hauptursache für LoD-Verletzungen. Wenn ein Objekt alle seine Interna offenlegt, beginnen Clients unweigerlich, diese transitiv zu durchlaufen. Die Lösung: Ersetzen Sie Getter durch Methoden, die sinnvolle Aktionen ausführen (Tell, Don’t Ask).

Statt user.address.city.name stellen Sie user.getCityName() bereit. Statt order.items.getTotal() stellen Sie order.getTotalPrice() bereit. Jede solche Methode kapselt eine Kette und schützt Clients vor Änderungen der internen Struktur. Laut Martin Fowler: „Refactoring, 2nd Edition“ (2019) ist das Ersetzen von transitivem Zugriff durch eine Vermittlermethode eine der vorteilhaftesten Refactorings in Bezug auf das Nutzen-Aufwand-Verhältnis.

Überprüfen Sie alle öffentlichen Getter, die veränderbare Objekte zurückgeben. Wenn ein Getter ein komplexes Objekt statt eines Primitivs zurückgibt, ist dies eine potenzielle LoD-Verletzung. Fügen Sie eine Methode hinzu, die die erforderliche Aktion ausführt, und schränken Sie den Zugriff auf den Getter ein.

Fassade für komplexe Subsysteme

Fassade (Facade) ist ein Architekturmuster, das eine einfache Schnittstelle zu einem komplexen Subsystem bereitstellt. Im Kontext von LoD ist eine Fassade eine Klasse, über die ein Client mit einer Gruppe von Objekten kommuniziert, ohne deren interne Struktur zu kennen. Repository in Android ist eine klassische Fassade, die Ketten von DataSource → API → Cache verbirgt.

kotlin
// Fassade: Repository verbirgt Kette von Datenquellen
class PaymentRepository(
    private val api: PaymentApi,
    private val cache: PaymentCache,
    private val analytics: AnalyticsTracker
) {
    suspend fun processPayment(amount: Double): Result {
        analytics.track("payment_start")
        val result = api.charge(amount)
        cache.save(result)
        return result
    }
}

// ViewModel weiß nichts von api, cache oder analytics
viewModel.processPayment(amount)

PaymentRepository ist eine Fassade: ViewModel ruft eine Methode auf, processPayment, und das Repository koordiniert API, Cache und Analysen intern. ViewModel hat keine Aufrufketten zu api.charge() oder cache.save() — das würde LoD verletzen. Die gesamte interne Struktur ist hinter einem einzigen Aufruf verborgen.

Häufige Fehler bei der Befolgung von LoD

Blinde Befolgung: Übermäßige Wrapper-Methoden

Übermäßige Wrapper — wenn ein Entwickler dutzende Vermittlermethoden erstellt, die einfach einen Aufruf von einer Klasse an eine andere delegieren. Order.getUserEmail() = user.email ist ein nutzloser Wrapper. LoD erfordert keine Wrapper für jedes Feld — es erfordert das Verbergen von Ketten, nicht von einzelnen einfachen Feldern.

Das Kriterium: Wenn ein Wrapper einfach ein Feld ohne Transformation und ohne Verbergen einer Kette zurückgibt, ist er nicht erforderlich. Order.getUserEmail() ist ein schlechter Wrapper, weil user.email ein direkter Zugriff auf ein Feld eines benachbarten Objekts ist und user ein direktes Feld von Order ist, was LoD erlaubt. Eine Verletzung wäre es, wenn Order user.getEmail() über zwei Schritte zurückgibt: zuerst user, dann email.

Erstellen Sie keine Wrapper für direkte Felder (der Zugriff auf ein Feld Ihres eigenen Objekts oder ein direktes Feld ist von LoD erlaubt). Erstellen Sie Wrapper, wenn ein Client beginnt, transitiv zu durchlaufen: a.b().c().d() → a.b().d() oder a.d().

Verwechslung von LoD mit dem Gesetz von Demeter für Daten

LoD gilt für Verhalten, nicht für Daten. Datenklassen (DTOs — einfache Datencontainer) sind nicht verpflichtet, LoD zu befolgen: Ihr Zweck ist es, Daten offenzulegen. OrderDTO.items[0].price ist keine LoD-Verletzung, da ein DTO per Definition eine Datenstruktur ist, kein Objekt mit Verhalten. Die Verwechslung zwischen Objekten und Datenstrukturen ist einer der häufigsten Fehler.

Die Unterscheidung traf Robert C. Martin: „Clean Code“ (2008): „Objekte verbergen Daten und legen Verhalten offen. Datenstrukturen legen Daten offen und haben kein Verhalten.“ LoD gilt für Objekte mit Verhalten. Für Datenstrukturen (DTOs, JSON-Modelle) sind Zugriffsketten zulässig. Sobald eine Datenstruktur eine Methode mit Logik erhält, wird sie zu einem Objekt und muss LoD befolgen.

Unterscheiden Sie: Wenn eine Klasse nur Felder ohne Methoden enthält (DTO), gilt LoD nicht. Wenn eine Klasse Methoden mit Logik enthält, ist LoD obligatorisch. Überprüfen Sie im Code-Review: Ist dies eine Datenklasse (DTO) oder ein Objekt (mit Methoden)?

Häufig gestellte Fragen

Was ist das Gesetz von Demeter in einfachen Worten?

Gesetz von Demeter (LoD): Ein Objekt kann nur mit engen Freunden kommunizieren — sich selbst, seinen Feldern, Parametern seiner Methoden und von ihm erstellten Objekten. Sie können keine Kette durchlaufen: a.getB().getC().doSomething() — das ist eine Verletzung.

Wie unterscheidet sich LoD von Tell, Don’t Ask?

LoD geht darum, MIT WELCHEN Objekten Sie interagieren können (nur unmittelbare Nachbarn). Tell, Don’t Ask geht darum, WIE Sie interagieren (fragen Sie nicht nach Daten, sagen Sie, es zu tun). Sie ergänzen sich: LoD schränkt den Kommunikationskreis ein, Tell Don’t Ask definiert die Art der Interaktion.

Wann kann LoD verletzt werden?

LoD kann für DTOs (Datenübertragungsobjekte) und einfache Datenstrukturen ohne Logik verletzt werden. Auch das Builder-Muster gilt nicht als Verletzung, da jeder Aufruf denselben Builder zurückgibt. Ausnahmen: Ketten in Stream API (map, filter) sind keine LoD-Verletzungen.

Wie prüft Detekt LoD in Android?

Detekt hat die Regel TooManyFunctions (indirekt), aber für die direkte Kettenprüfung verwenden Sie die Regel DataClassShouldBeImmutable und benutzerdefinierte Prüfungen über bindingReference. Konfigurieren Sie CI: Ketten mit mehr als 2 Aufrufen — Warnung, mehr als 3 — Build-Fehler.

Wie prüft SwiftLint LoD in iOS?

SwiftLint hat keine eingebaute Regel für LoD, aber Sie können eine benutzerdefinierte Regel über Regex erstellen: Ketten wie \..+\.\..+\.\..+ (3+ Punktaufrufe). Alternative: Verwenden Sie die Regel nimble_operator und erweitern Sie sie, um lange Ketten zu erkennen.

Zusammenfassung

  • LoD (Law of Demeter / Prinzip des geringsten Wissens) — eine Regel: Ein Objekt interagiert nur mit seinen unmittelbaren Freunden.
  • Aufrufketten (Train Wrecks) — die hauptsächliche LoD-Verletzung: a.b().c().d() erzeugt versteckte Abhängigkeiten von der gesamten Kette von Typen.
  • Tell, Don’t Ask — ein verwandtes Prinzip: Delegieren Sie die Aktion an das Objekt, anstatt seine Daten für die externe Verarbeitung anzufordern.
  • Breite Getter — eine Ursache von Verletzungen: Wenn ein Objekt alle Felder offenlegt, beginnen Clients, sie transitiv zu durchlaufen.
  • Fassade (Facade) — ein Muster zur Einhaltung von LoD: Eine einheitliche Schnittstelle verbirgt ein komplexes Subsystem vor dem Client.
  • DTOs und Datenklassen — eine Ausnahme: Datenstrukturen müssen LoD nicht befolgen, da sie kein Verhalten haben.
  • Automatisierung über Detekt (Android) oder benutzerdefiniertes SwiftLint (iOS) reduziert die Anzahl der LoD-Verletzungen in der Codebasis.

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch