Frage

Wikipedia-Artikel über Gesetz von Demeter sagt:

  

Das Gesetz lautet schlicht und einfach als „verwenden nur einen Punkt“.

Jedoch a Fluent Interface wie folgt aussehen:

static void Main(string[] args)
{
   new ZRLabs.Yael.Pipeline("cat.jpg")
        .Rotate(90)
        .Watermark("Monkey")
        .RoundCorners(100, Color.Bisque)
        .Save("test.png");
}

Das Gleiche gilt für das geht zusammen?

War es hilfreich?

Lösung

Nun, die kurze Definition des Gesetzes verkürzt es zu viel. Das eigentliche „Gesetz“ (in Wirklichkeit Beratung über gutes API-Design) sagt im Grunde: Nur Zugriff Objekte, die Sie selbst erstellt haben, oder wurden Sie als Argument übergeben. Zugriff Sie keine Gegenstände indirekt über andere Objekte. Methoden der fließend Schnittstellen zurückgeben oft das Objekt selbst, so dass sie nicht gegen das Gesetz verstoßen, wenn Sie das Objekt wieder verwenden. Andere Methoden erstellen Objekte für Sie, so dass es keine Verletzung auch nicht.

Beachten Sie auch, dass das „Gesetz“ ist nur eine Best Practices Beratung für „klassischen“ APIs. Fluent-Schnittstellen sind ein völlig anderer Ansatz zum API-Design und nicht mit dem Gesetz des Demeter ausgewertet werden können.

Andere Tipps

Nicht unbedingt. „Einen Punkt nur“ ist eine ungenaue Zusammenfassung des Gesetzes von Demeter.

Das Gesetz der Demeter schreckt die Verwendung von mehreren Punkten, wenn jeder Punkt das Ergebnis eines anderen Objekts darstellt, z.

  • Erster Punkt ist ein Verfahren aus ObjectA genannt, ein Objekt vom Typ ObjectB
  • Rückkehr
  • Next Punkt ist ein Verfahren nur in ObjectB, ein Objekt vom Typ ObjectC Rückkehr
  • Weiter dot ist eine Eigenschaft nur in ObjectC
  • ad infinitum

Aber zumindest meiner Meinung nach ist das Gesetz von Demeter nicht verletzt, wenn das Rückgabeobjekt eines jeden Punktes immer 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 Sortieren () gibt die gleiche Art von Objekt als die ursprüngliche Liste. Das Gesetz des Demeter nicht verletzt wird. Die folgende Liste nur seine unmittelbaren Freunde gesprochen

Dass gesagt wird nicht alle fließend Schnittstellen verletzen das Gesetz von Demeter, nur so lange, wie sie die gleiche Art wie ihre Anrufer zurück.

Ja, obwohl Sie etwas Pragmatismus, um die Situation zu beantragen. Ich nehme immer das Gesetz des Demeter als Richtlinie als eine Regel gegenüber.

Sicherlich können Sie auch mögen folgendes vermeiden:

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

vielleicht ersetzen mit:

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

Da immer mehr von uns ORM verwenden, die im Allgemeinen die gesamte Domäne als Objekt Graph präsentiert könnte es eine Idee sein akzeptabel „scope“ für ein bestimmtes Objekt zu definieren. Vielleicht sollen wir das Gesetz des demeter nehmen zu lassen vermuten, dass Sie nicht das gesamte Graphen als erreichbar Karte sollten.

Der Geist des Gesetzes Demeter ist, dass eine Objektreferenz oder Klasse angegeben, sollten Sie die Eigenschaften einer Klasse vermeiden Zugriff auf die mehr als eine Unter Eigenschaft oder Methode entfernt ist, da das wird eng Paar die beiden Klassen, die unbeabsichtigt sein könnte und Wartbarkeit zu Problemen führen.

Fluent-Schnittstellen sind eine akzeptable Ausnahme dem Gesetz, da sie sind bedeutet zumindest etwas eng gekoppelt sein, wie alle Eigenschaften und Methoden sind die Bedingungen einer Mini-Sprache, die zusammengesetzt sind, zusammen bilden funktionelle Sätze.

1) Es verstößt es 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:

Es gibt kein Problem mit Ihrem Beispiel. Schließlich sind Drehen Sie, Watermarking, etc ... immer das gleiche Bild. Ich glaube, Sie zu einer Pipeline reden Objekt die ganze Zeit, so lange, wie Sie Ihren Code nur von der Klasse der Pipeline abhängig ist, sind Sie nicht LoD verletzen.

scroll top