2008-09-15 13 views

Antwort

71

Nun, die kurze Definition des Gesetzes verkürzt es zu sehr. Das echte "Gesetz" (in Wirklichkeit ein Hinweis auf gutes API-Design) sagt im Wesentlichen: Greifen Sie nur auf Objekte zu, die Sie selbst erstellt haben, oder wurden sie Ihnen als Argument übergeben. Greifen Sie nicht indirekt über andere Objekte auf Objekte zu. Methoden flüssiger Interfaces geben oft das Objekt selbst zurück, so dass sie nicht gegen das Gesetz verstoßen, wenn Sie das Objekt erneut verwenden. Andere Methoden erstellen Objekte für Sie, also gibt es auch keine Verletzung.

Beachten Sie auch, dass das "Gesetz" nur eine Best Practices-Empfehlung für "klassische" APIs ist. Fluent Interfaces sind ein völlig anderer Ansatz zum API-Design und können nicht mit dem Demeter-Gesetz bewertet werden.

+11

Man könnte argumentieren, dass eine fließende Schnittstelle nicht gegen das Demeter-Gesetz verstößt, weil man nur auf das gleiche Objekt in einer Punktkette zugreift. – MSN

+0

Eine zweite Möglichkeit, dies zu betrachten, besteht darin, dass eine fließende Schnittstelle einfach eine alternative, kompakte Art ist, sequenzierte Operationen so durchzuführen, dass eine Zustandsveränderung abstrahiert wird, da die Ergebnisse jedes Zwischenschritts implizit sind. –

8

Ja, obwohl Sie auf die Situation etwas Pragmatismus anwenden müssen. Ich nehme immer das Gesetz von Demeter als Richtlinie im Gegensatz zu einer Regel.

Sicherlich können Sie auch folgendes vermeiden wollen:

CurrentCustomer.Orders[0].Manufacturer.Address.Email(text); 

vielleicht ersetzen mit:

CurrentCustomer.Orders[0].EmailManufacturer(text); 

Je mehr von uns ORM verwenden, die im Allgemeinen die gesamte Domäne als Objekt Graph zeigt es könnte eine Idee sein, einen akzeptablen "Geltungsbereich" für ein bestimmtes Objekt zu definieren. Vielleicht sollten wir das Gesetz von Demeter nehmen, um vorzuschlagen, dass Sie den gesamten Graphen nicht als erreichbar abbilden sollten.

+3

Ich denke, die Einzel Prinzip Verantwortung gezogen werden könnten,„zu bedeuten haben kein Verfahren auf Business Objekt zum Versenden von E-Mails ". –

23

Nicht unbedingt. "Nur einen Punkt verwenden" ist eine ungenaue Zusammenfassung des Demeter-Gesetzes.

Das Gesetz des Demeter die Verwendung von mehreren Punkten abschreckt, wenn jeder Punkt das Ergebnis eines anderen Objekt darstellt, zB:

  • erster Punkt ist eine Methode aus ObjectA genannt, ein Objekt vom Typ zurückkehr ObjectB
  • Nächster Punkt ist ein Verfahren nur in ObjectB verfügbar, ein Objekt vom Typ Rückkehr ObjectC
  • nächster Punkt eine Eigenschaft ist nur in ObjectC
  • ad infinitum

jedoch zumindest meiner Meinung nach ist das Gesetz von Demeter nicht, wenn das Rückgabeobjekt eines jeden Punktes verletzt noch der gleiche Typ wie der ursprünglichen Anrufer ist:

var List<SomeObj> list = new List<SomeObj>(); 
//initialize data here 
return list.FindAll(i => i == someValue).Sort(i1, i2 => i2 > i1).ToArray(); 

In dem obigen Beispiel beid FindAll () und Sort() geben denselben Objekttyp wie die ursprüngliche Liste zurück. Das Gesetz von Demeter wird nicht verletzt: Die Liste sprach nur mit seinen unmittelbaren Freunden.

Das sagte nicht alle fließenden Schnittstellen verletzen das Gesetz der Demeter, so lange sie den gleichen Typ wie ihre Anrufer zurückgeben.

6

Der Sinn des Demeter-Gesetzes besteht darin, dass Sie bei einem Objektverweis oder einer Objektklasse auf die Eigenschaften einer Klasse mit mehr als einer Untereigenschaft oder Methode verzichten sollten, da dies die beiden Klassen fest miteinander koppelt unbeabsichtigt und kann Probleme mit der Wartbarkeit verursachen.

Fließende Schnittstellen sind eine akzeptable Ausnahme vom Gesetz, da sie gemeint sind zumindest etwas eng gekoppelt werden, da alle Eigenschaften und Methoden die Begriffe einer Minisprache sind, die zusammen zu funktionellen Sätzen zusammengesetzt sind.

1

Es gibt kein Problem mit Ihrem Beispiel. Immerhin drehen Sie, Wasserzeichen, etc ... immer das gleiche Bild. Ich glaube, Sie reden ständig mit einem Pipeline-Objekt, so lange Ihr Code nur von der Klasse der Pipeline abhängt, verletzen Sie LoD nicht.

6

1) Es verletzt es überhaupt nicht.

Der Code entspricht

var a = new ZRLabs.Yael.Pipeline("cat.jpg"); 
a = a.Rotate(90); 
a = a.Watermark("Monkey"); 
a = a.RoundCorners(100, Color.Bisque); 
a = a.Save("test.png"); 

2) As Good Ol‘Phil Haack sagt: The Law of Demeter Is Not A Dot Counting Exercise

Verwandte Themen