Das Gesetz von Demeter besagt Folgendes:
- 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.
In C # 6.0 wurde ein neuer Operator eingeführt, der als nullbedingter Operator bezeichnet wird . IMHO erleichtert es die Codierung und verbessert die Lesbarkeit. Aber es macht es auch einfacher, mehr gekoppelten Code zu schreiben, da es einfacher ist, durch Klassenfelder zu navigieren, die bereits auf NULL prüfen (so etwas wie var x = A?.B?.C?.D?.E?.F?
).
Stimmt es, dass dieser neue Betreiber gegen das Gesetz von Demeter verstößt?
c#
design-patterns
object-oriented-design
Arthur Rizzo
quelle
quelle
A?.B?.C?.D?.E?.F?
dies gegen die Regeln verstoßen würde? Bei LoD geht es nicht darum, wie viele Punkte es gibt, und wenn die aufrufende Methode solche Informationen über die Struktur enthält, die nicht gegen ihre Punkte verstößt , wäre ein solcher Aufruf durchaus akzeptabel. Dass ein solcher Code könnte LoD verletzen ist nicht genug , um zu sagen , dass alle Verwendungen es tun verletzen LoD.X.Y.Z.W.U
gegen das "Gesetz" verstößt. Aber meiner Erfahrung nach ist Code in 90% der Fälle einfach nur hässlich gekoppelter Code..?
verstößt nicht mehr gegen das LoD als+
oder-
.Antworten:
Nein *
* Der Null-Bedingungsoperator ist ein Tool innerhalb der Sprache und des .NET-Frameworks. Jedes Tool kann auf eine Weise missbraucht und verwendet werden, die die Wartbarkeit einer bestimmten Anwendung beeinträchtigen kann.
Aber die Tatsache , dass ein Werkzeug kann missbraucht werden , bedeutet nicht zwangsläufig , dass es hat missbraucht werden , um, noch , dass das Werkzeug gegen ein bestimmtes Prinzip (n) , die gehalten werden können.
Das Gesetz von Demeter und andere sind Richtlinien, wie Sie Ihren Code schreiben sollten. Es zielt auf den Menschen ab, nicht auf die Werkzeuge. Die Tatsache, dass die C # 6.0-Sprache ein neues Tool enthält, wirkt sich nicht unbedingt darauf aus, wie Sie Ihren Code schreiben und strukturieren sollten.
Bei jedem neuen Tool muss bewertet werden, ob der Typ, der den Code verwaltet, ein gewalttätiger Psychopath ist . Beachten Sie erneut, dass dies eine Anleitung für die Person ist, die den Code schreibt, und nicht für die verwendeten Tools.
quelle
foo = new FiveDMatrix(); foo.get(0).get(0).get(0).get(0).set(0,1);
wäre in Ordnung (und nicht schlimmer alsfoo[0][0][0][0][0] = 1
) ... und viele andere Situationen, in denen dies nicht gegen die LoD verstößt.Dom file = prase("some.xml"); file.get(tag1).getChild().get(tag2).getChild() ...
- es ist ein Problem der Verarbeitung der Struktur von etwas dummem Code. Es ist kein Fremder ... es ist einfach dumm. Das.?
wird in solchen Strukturen sehr nützlich.Art von.
Wenn Sie nur einen Zugriff (
a?.Foo
) ausführen, entspricht dies:was die meisten Leute zustimmen würden, ist kein Verstoß gegen das Gesetz von Demeter. Zu diesem Zeitpunkt ist es nur syntaktischer Zucker, um die Lesbarkeit zu verbessern.
Mehr als das, und es würde wahrscheinlich das Gesetz von Demeter verletzen, und diese Funktion fördert diese Art der Verwendung. Ich würde sogar sagen, dass die oben genannte "gute" Verwendung allein nicht ausreicht, um diese Art der Änderung der Sprache zu rechtfertigen. Ich gehe daher davon aus, dass sie die weniger klar gute Verwendung unterstützt.
Das Gesetz von Demeter ist jedoch kein Gesetz an sich, sondern eher eine Richtlinie. Viele Codes verstoßen dagegen und funktionieren gut. Manchmal ist die Einfachheit des Designs oder des Codes mehr wert als das Risiko, das durch die Verletzung des Gesetzes von Demeter entsteht.
quelle
a?.Func1(x)?.Func2(y)
Der Null-Koaleszenzoperator ist etwas anderes.Betrachten wir sowohl den Operator als auch die stark verkettete Verwendung, die Sie dafür haben.
Dies
.?A
hängt von der Kenntnis der Klasse ab, bei der es sich um den Wert left handelt, und von dem Typ, der von der Methode zurückgegeben wird, wie dies auch der.A != null
Fall ist. Es muss bekannt sein, dass dieA
Eigenschaft vorhanden ist und einen vergleichbaren Wert zurückgibtnull
.Wir können nur argumentieren, dass dies gegen das Gesetz von Demeter verstößt, wenn typisierte Eigenschaften dies tun. Wir sind nicht einmal gezwungen,
A
einen konkreten Typ zu haben (sein Wert könnte von einem abgeleiteten Typ sein). Die Kopplung hier ist minimal.Betrachten wir nun
var x = A?.B?.C?.D?.E?.F
.Dies bedeutet,
A
dass der Typ null sein muss oder eineB
Eigenschaft haben muss, der Typ null sein muss oder eineC
Eigenschaft haben muss, und so weiter, bis der Typ derE
Eigenschaft null sein kann oder könnte eineF
Eigenschaft haben.Mit anderen Worten, wir müssen dies entweder mit einer statisch typisierten Sprache tun oder eine Einschränkung für die Typen anwenden, die zurückgegeben werden können, wenn die Typisierung locker ist. C # verwendet in den meisten Fällen statische Typisierung, sodass wir nichts geändert haben.
Wenn wir das hätten, würde der folgende Code ebenfalls gegen das Gesetz verstoßen:
Welches ist genau das gleiche . Dieser Code, der ist mit der Kopplung verschiedenen Elementen Bedürfnisse zu „weiß“ über die gesamte Kette der Kupplung, aber es ist Code, der so nicht das Gesetz von Demeter verstoßen zu tun, mit jeder Einheit mit einer gut definierten Kopplung mit der nächste.
quelle
var x = A?.B?.C?.D?.E?.F
als alle anderen, auch wenn sie am Ende die gleichen sind.A?.B?.C?.D?.E?.F
weil weniger falsch sein kann. Entweder sollten wir versuchen,F
über diesen Pfad zu gelangen , oder wir sollten nicht, während die längere Form Fehler enthalten könnte, und der Fehler, dass es nicht das Richtige ist, was zu tun ist.A.B.C.D
. Es ist viel einfacher, auf eine einzige Sache zu achten (Zugriff auf verkettete Eigenschaften), als auf zwei verschiedene Dinge, die von einem ziemlich irrelevanten Detail abhängen (Nullprüfung)Das Objekt kann erstellt werden, um Verhalten zu kapseln oder Daten zu speichern, und Objekte können erstellt werden, um mit externem Code geteilt zu werden oder um privat von ihrem Ersteller gehalten zu werden.
Auf Objekte, die zum Zwecke der Einkapselung von Verhalten (unabhängig davon, ob sie gemeinsam genutzt werden oder nicht) oder zur gemeinsamen Nutzung mit externem Code (unabhängig davon, ob sie Verhalten oder Daten einkapseln) erstellt wurden, sollte im Allgemeinen über ihre Oberflächenschnittstelle zugegriffen werden. Bei der Erstellung von Datenobjekten zur ausschließlichen Verwendung durch ihren Ersteller gelten jedoch nicht die normalen Law-of-Demeter-Gründe zur Vermeidung eines "tiefen" Zugriffs. Wenn ein Teil einer Klasse, in der Daten im Objekt gespeichert oder bearbeitet werden, so geändert wird, dass ein anderer Code angepasst werden muss, kann garantiert werden, dass der gesamte Code aktualisiert wird, da das Objekt - wie oben erwähnt - für das Objekt erstellt wurde die ausschließliche Verwendung einer Klasse.
Während ich das denke? Der Operator hätte vielleicht besser entworfen werden können. Es gibt genügend Situationen, in denen Objekte verschachtelte Datenstrukturen verwenden, so dass der Operator viele Anwendungsfälle hat, die nicht gegen die Prinzipien des Gesetzes von Demeter verstoßen würden. Die Tatsache, dass es zur Verletzung der LoD verwendet werden könnte, sollte nicht als Argument gegen den Operator gewertet werden, da es nicht schlechter ist als das "." Betreiber in dieser Hinsicht.
quelle