16 Stimmen

Verstößt Dependency Injection gegen das Gesetz von Demeter?

Ich habe die Injektion von Abhängigkeiten zu meinem Code hinzugefügt, weil es den Code viel einfacher macht, durch Mocking einen Unit-Test durchzuführen.

Ich verlange jedoch, dass Objekte, die weiter oben in meiner Aufrufkette stehen, Kenntnis von Objekten haben, die weiter unten in der Aufrufkette stehen.

Verstößt dies gegen das Gesetz der Demeter? Wenn ja, ist das von Bedeutung?

Beispiel: Eine Klasse A hat eine Abhängigkeit von einer Schnittstelle B. Die zu verwendende Implementierung dieser Schnittstelle wird in den Konstruktor der Klasse A injiziert. Jeder, der die Klasse A verwenden will, muss nun auch einen Verweis auf eine Implementierung von B haben und kann deren Methoden direkt aufrufen, d.h. er hat Kenntnis von deren Unterkomponenten (Schnittstelle B)

Wikipedia sagt über das Gesetz der Demeter: "Der grundlegende Gedanke ist, dass ein bestimmtes Objekt so wenig wie möglich von der Struktur oder den Eigenschaften eines anderen Objekts (einschließlich seiner Teilkomponenten) annehmen sollte."

1 Stimmen

Können Sie einen Beispielcode veröffentlichen? Wenn Sie foo.bar().baz() machen, dann verstoßen Sie gegen das Gesetz von Demeter. Wollen Sie damit sagen, dass Sie am Ende so vorgehen?

13voto

Mark Roddy Punkte 25266

Dependency Injection KANN das Gesetz von Demeter brechen. Wenn Sie die Konsumenten dazu zwingen, die Injektion der Abhängigkeiten durchzuführen. Dies kann durch statische Fabrikmethoden und DI-Frameworks vermieden werden.

Sie können beides haben, indem Sie Ihre Objekte so gestalten, dass sie die Übergabe der Abhängigkeiten erfordern, und gleichzeitig einen Mechanismus haben, um sie zu verwenden, ohne die Injektion explizit durchzuführen (Fabrikfunktionen und DI-Frameworks).

0 Stimmen

Ich denke, Sie haben es auf den Punkt gebracht. Einige der anderen Antworten auf diese Frage sind nicht auf die spezifische Situation des Fragestellers ausgerichtet.

0 Stimmen

Können Sie bitte den Begriff "Verbraucher" näher erläutern?

0 Stimmen

In diesem Fall ist ein Konsument einer Klasse jeder andere Code, der Methoden dieser Klasse aufruft.

5voto

aku Punkte 118808

Wie wird sie gebrochen? DI passt perfekt zur Idee des geringsten Wissens. DI ermöglicht eine geringe Kopplung - die Objekte sind weniger voneinander abhängig.

Mit Verweis auf Wikipedia:

...ein Objekt A kann einen Dienst anfordern (eine Methode aufrufen) eine Methode) einer Objektinstanz B anfordern, aber Objekt A kann nicht "durch" Objekt B zugreifen, um auf ein anderes Objekt zuzugreifen...

Normalerweise funktioniert DI genau so, d.h. Sie nutzen Dienste, die von injizierten Komponenten bereitgestellt werden. Wenn Ihr Objekt versucht, auf einige der Abhängigkeiten von B zuzugreifen, d.h. wenn es viel über B weiß, führt das zu einer hohen Kopplung und bricht die Idee der DI

Ich benötige jedoch höhere Objekte meiner Aufrufkette Kenntnisse über Objekten weiter unten in der Aufrufkette

Ein Beispiel?

2voto

David M. Karr Punkte 12795

Wenn ich Sie richtig verstehe, wird dies nicht durch die Verwendung von Dependency Injection verursacht, sondern durch die Verwendung von Mocking-Strategien, bei denen Sie die Funktionsaufrufe, die Sie von einer Methode erwarten, angeben müssen. Das ist in vielen Situationen durchaus akzeptabel, aber das bedeutet natürlich, dass man etwas über die Methode wissen muss, die man aufruft, wenn man angegeben hat, was sie Ihrer Meinung nach tun soll.

Das Schreiben guter Software erfordert ein Abwägen von Kompromissen. Je vollständiger die Implementierung wird, desto inkonsistenter wird sie. Sie müssen entscheiden, welche Risiken diese Inkonsistenzen mit sich bringen und ob sie den Wert wert sind, der durch ihr Vorhandensein geschaffen wird.

1voto

John Mulder Punkte 9047

Verstößt es gegen das Gesetz?
Streng genommen glaube ich schon.
Ist das wichtig?
Die größte Gefahr bei einem Verstoß gegen das Gesetz besteht darin, dass Sie Ihren Code brüchiger machen.
Wenn man sich wirklich nur auf die Tests beschränkt, scheint die Gefahr nicht allzu groß zu sein.
Milderung
Mein Verständnis der Das Gesetz der Demeter ist, dass es "Wrapper-Methoden" gibt, die einen direkten Aufruf von Objekten verhindern.

1voto

Franci Penov Punkte 73239

Das Demeter-Gesetz besagt, dass die Methode M des Objekts O Methoden von Objekten aufrufen kann, die innerhalb von M erstellt/instantiiert wurden. Es gibt jedoch keine Angaben darüber, wie diese Objekte erstellt wurden. Ich denke, es ist völlig in Ordnung, ein zwischengeschaltetes Objekt zu verwenden, um diese zu erzeugen, solange der Zweck dieses Objekts im Leben nur darin besteht, andere Objekte in Ihrem Namen zu erzeugen. In diesem Sinne verstößt DI nicht gegen das Gesetz der Demeter.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X