Darf eine Klasse nach Demeters Gesetz eines ihrer Mitglieder zurückgeben?
Ja, das ist es mit Sicherheit.
Schauen wir uns die wichtigsten Punkte an :
- Jede Einheit sollte nur begrenzte Kenntnisse über andere Einheiten haben: nur Einheiten, die "eng" mit der aktuellen Einheit verbunden sind.
- Jede Einheit sollte nur mit ihren Freunden sprechen. Sprich nicht mit Fremden.
- Sprechen Sie nur mit Ihren direkten Freunden.
Alle drei lassen Sie eine Frage stellen: Wer ist ein Freund?
Bei der Entscheidung, was zurückgegeben werden soll, schreibt das Gesetz von Demeter oder das Prinzip des geringsten Wissens (LoD) nicht vor, dass Sie sich gegen Programmierer verteidigen, die darauf bestehen, gegen das Gesetz zu verstoßen. Es schreibt vor, dass Sie Codierer nicht dazu zwingen, dagegen zu verstoßen.
Diese zu verwirren ist genau der Grund, warum so viele glauben, ein Setter müsse immer ins Leere gehen. Nein. Sie müssen die Möglichkeit einräumen, Abfragen (Getter) durchzuführen, die den Status des Systems nicht ändern. Das ist die grundlegende Trennung von Befehlsabfragen .
Bedeutet dies, dass Sie sich frei in eine Codebasis vertiefen können, die alles miteinander verkettet, was Sie wollen? Verketten Sie nur das, was zusammen verkettet werden sollte. Andernfalls könnte sich die Kette ändern und plötzlich ist Ihr Zeug kaputt. Dies ist, was mit Freunden gemeint ist.
Lange Ketten können für ausgelegt werden. Fließende Schnittstellen, iDSL, ein Großteil von Java8 und der gute alte StringBuilder ermöglichen den Aufbau langer Ketten. Sie verletzen LoD nicht, weil alles in der Kette zusammenarbeiten soll und versprochen wird, weiter zusammenzuarbeiten. Sie verletzen Demeter, wenn Sie Dinge aneinander reihen, die noch nie voneinander gehört haben. Freunde sind diejenigen, die versprochen haben, Ihre Kette am Laufen zu halten. Freunde von Freunden nicht.
Abgesehen von Klassen, die speziell für die Rückgabe von Objekten bestimmt sind - wie Factory- und Builder-Klassen - ist es in Ordnung, wenn eine Methode ein Objekt zurückgibt, z. ?
Dies schafft nur die Möglichkeit, gegen Demeter zu verstoßen. Dies ist keine Verletzung. Das ist nicht unbedingt schlecht.
Und wenn es gegen das Demeter-Gesetz verstößt, wäre es dann von Bedeutung, wenn das zurückgegebene Objekt ein unveränderliches Objekt ist, das ein Datenelement darstellt und nur Getter für diese Daten enthält (2)?
Unveränderlich ist hier gut, aber irrelevant. Dinge durch eine längere Kette zu erreichen, macht es nicht besser. Was es besser macht, ist das Trennen des Erhaltens vom Verwenden. Wenn Sie verwenden, fragen Sie nach dem, was Sie als Parameter benötigen. Gehen Sie nicht auf die Jagd, indem Sie sich mit Fremden befassen.
Im Pseudocode:
Ich vermute, dass Demeters Gesetz ein Muster wie das obige verbietet. Was kann ich tun, um sicherzustellen, dass doSomethingElse () aufgerufen werden kann, ohne das Gesetz zu verletzen (3)?
Bevor ich darüber x.doSomethingElse(a)
spreche, verstehe ich , dass du grundlegend geschrieben hast
b.getA().doSomething()
Jetzt ist LoD keine Punktezählübung . Aber wenn Sie eine Kette erstellen, sagen Sie, dass Sie wissen, wie man eine A
(mit B
) erhält und wie man eine verwendet A
. Nun gut A
und B
besser enge Freunde sein, weil du sie einfach zusammengekoppelt hast.
Wenn Sie nur darum gebeten hätten, Ihnen etwas A
Ähnliches zu geben, das Sie verwenden könnten, A
und es hätte Sie nicht interessiert, woher es kommt, und Sie B
könnten ein Leben führen, das glücklich und frei von Ihrer Obsession ist, A
davon zu leben B
.
Was die Herkunft x.doSomethingElse(a)
ohne Details x
angeht, hat LoD überhaupt nichts zu sagen.
LoD kann die Trennung von Nutzung und Konstruktion fördern . Aber ich werde darauf hinweisen, wenn Sie jedes Objekt religiös als nicht freundlich behandeln, werden Sie nicht in der Lage sein, Code in statischen Methoden zu schreiben. Sie können auf diese Weise einen wunderbar komplexen Objektgraphen erstellen, aber irgendwann müssen Sie eine Methode darauf aufrufen, um das Ding zum Laufen zu bringen. Sie müssen sich nur entscheiden, wer Ihre Freunde sind. Daran führt kein Weg vorbei.
Ja, eine Klasse darf eines ihrer Mitglieder unter LoD zurückgeben. Wenn Sie dies tun, sollten Sie klarstellen, ob dieses Mitglied mit Ihrer Klasse befreundet ist. Andernfalls versucht ein Client möglicherweise, Sie an diese Klasse zu koppeln, indem Sie Sie verwenden, um sie abzurufen, bevor Sie sie verwenden. Das ist wichtig, denn jetzt muss das, was Sie zurückgeben, diese Verwendung immer unterstützen.
Es gibt viele Fälle, in denen dies einfach kein Problem darstellt. Sammlungen können dies einfach ignorieren, weil sie mit allem, was sie verwendet, befreundet sein sollen. Ähnlich wertvolle Objekte sind mit jedem freundlich. Wenn Sie jedoch ein Dienstprogramm zur Adressvalidierung geschrieben haben, das ein Mitarbeiterobjekt anfordert, aus dem eine Adresse extrahiert wurde, und dann nur nach der Adresse fragen, sollten Sie hoffen, dass sowohl Mitarbeiter als auch Adresse aus derselben Bibliothek stammen.