Ist das 'Demeter-Gesetz' auf öffentliche / API-Methodensignaturen anwendbar?

10

Angesichts der Tatsache, dass Änderungen an der API / öffentlichen Methodensignatur minimal sein sollten, um zu verhindern, dass die Clientcodes, die diese Methoden verwenden, beschädigt werden, habe ich mich gefragt, ob das Demeter-Gesetz auf diese weniger anwendbar ist.

Ein einfaches Beispiel:

class Account() {
   double balance;
   public void debit(Transaction t) {
      balance -= t.getAmount();
   }
}

Beachten Sie, dass die Abbuchungsmethode das Transaktionsobjekt und nicht nur den doppelten Betrag übergibt (das 'Gesetz von Demeter' würde, so wie ich es verstehe, nur die erforderlichen Informationen übergeben, in diesem Fall nur den Betrag, nicht das Transaktionsobjekt ... ). Der Grund dafür ist, dass die Methode in Zukunft möglicherweise neben dem Betrag noch einige andere Transaktionseigenschaften erfordert. Soweit ich weiß, wird dies verhindern, dass die Methodensignatur durch Hinzufügen eines neuen Parameters in Zukunft beschädigt wird.

Ist dies dann eine vernünftige Wahl? Oder fehlt mir etwas?

Carlos Jaime C. De Leon
quelle

Antworten:

3

Dies verstößt jedoch nicht gegen das Gesetz von Demeter.

Formal gesehen verlangt das Demeter-Gesetz für Funktionen, dass eine Methode M eines Objekts O nur die Methoden der folgenden Arten von Objekten aufrufen darf:

  • O selbst
  • Ms Parameter
  • alle innerhalb von M erstellten / instanziierten Objekte
  • O's direkte Komponentenobjekte
  • eine globale Variable, auf die O im Bereich von M zugreifen kann

Wikipedia: Gesetz von Demeter

Die Transaktion ist ein Argument für die Debitmethode, daher ist der Aufruf von t.getAmount () in Ordnung.

Bearbeiten: Falsch verstanden, Sie sagen, das LoD würde Sie den Betrag der Transaktion übergeben lassen, nicht ein Transaktionsobjekt. Wenn dies der Fall ist, dann denke ich, ist dies ein guter Ort, um es zu brechen, da Sie wissen, dass Sie in Zukunft mehr vom Transaktionsobjekt benötigen werden. Das Einkapseln von Grundelementen in Objekte auf Domänenebene ist eine weitere gute Programmierpraxis.

Edit 2: Nachdem man gelesen hat, dass in Zukunft möglicherweise mehr benötigt wird, könnte man dies auch als unnötige Vergoldung ansehen. Es reicht aus, eine Methode bereitzustellen, die jetzt ein Double (oder besser eine Money-Klasse) benötigt. Wenn Sie später ein Transaktionsargument benötigen, ist es nicht katastrophal, eine zweite Signatur für eine Transaktion bereitzustellen, aber weiterhin die ursprüngliche Signatur zu unterstützen. Es ist nicht so, als würden Sie zwei Methoden implementieren, eine würde die andere aufrufen.

Sean
quelle
Danke für deinen Beitrag. Ich stimme den Kapselungsprimitiven in Domänenobjekten zu. Nur Ihr Punkt in Edit 2, Sie sagen, es ist nicht katastrophal, eine neue 2. Signatur hinzuzufügen, aber das würde bedeuten, dass der Code in Client-Code geändert wird, der jetzt 2 Parameter anstelle von einem übergeben sollte. An diesem zweiten Punkt zögere ich, mich darauf zu einigen ...
Carlos Jaime C. De Leon
Edit 2 ist subjektiv, da stimme ich zu.
Sean
0

Wenn Sie vorhaben, die AccountKlasse in Zukunft zu erweitern, würde ich sagen, dass dies eine Situation ist, in der Transactiones allgemeiner wäre , das Objekt allgemeiner zu machen, um die Regeln des Gesetzes zu biegen.

Zum Beispiel:

public class Amount {

    public void process( Transaction t ) {
        ....
    }
}

public abstract class Transaction {

    public String getType();

}

Ich glaube, ich bin ein bisschen von der ursprünglichen Frage abgewichen, aber mein Punkt ist, dass, obwohl Sie vielleicht befürchten, dass Sie vom Gesetz von Demeter abweichen, die Vorteile diesbezüglich die negativen überwiegen.

Chooban
quelle