2009-11-10 6 views
18

In den letzten paar Tagen habe ich ziemlich viel über Abhängigkeitsinjektion/Inversion von Kontrolle/Inversion von Abhängigkeit gelesen. I denke, dass, jetzt ist mein Verständnis des Konzepts viel besser. Aber ich bekomme immer noch nicht aus Wikipedia:Abstraktionen sollten nicht von Details abhängen. Details sollten von Abstraktionen abhängen?

A. High-Level-Module sollten nicht von Low-Level-Module abhängen. Beide sollten von Abstraktionen abhängen. B. Abstraktionen sollten nicht von Details abhängen. Details sollten von Abstraktionen abhängen.

Ich verstehe den Teil Hochrangigen Module sollten nicht hängen von Low-Level-Module. Aber ich bin verwirrt über Abstraktionen und Details. Kann jemand bitte sie für mich vereinfachen. Vielen Dank.

Antwort

28

Es bedeutet, dass wenn sich die Details ändern, sollten sie die Abstraktion nicht beeinflussen. Die Abstraktion ist die Art und Weise, wie Clients ein Objekt anzeigen. Was im Inneren des Objekts passiert, ist nicht wichtig. Nehmen wir zum Beispiel ein Auto, die Pedale, das Lenkrad und der Schalthebel sind Abstraktionen dessen, was im Inneren des Motors passiert. Sie hängen jedoch nicht von den Details ab, denn wenn jemand meinen alten Motor gegen einen neuen auswechselt, sollte ich immer noch in der Lage sein, das Auto zu fahren, ohne zu wissen, dass sich der Motor geändert hat.

Die Details auf der anderen Seite müssen dem entsprechen, was die Abstraktion sagt. Ich möchte keinen Motor einbauen, der die Bremsen plötzlich doppelt so schnell macht wie das Auto. Ich kann Bremsen nach Belieben wieder herstellen, solange sie sich äußerlich so verhalten.

+2

Ich mag die OP hatte Probleme, dieses Konzept zu verstehen - große prägnante und klare Antwort danke. –

1

Beispiel für die Abstraktion und die Details: Ein Stream bietet eine Schnittstelle zum Lesen eines Tokens. Das ist eine Abstraktion.

Eine Stream-Implementierung des Streams ist verpflichtet, die durch die Abstraktion definierte Schnittstelle zu implementieren: deshalb kommt es darauf an. Wenn es eine andere Schnittstelle bietet (eine, um 100 Zeichen gleichzeitig zu lesen), kann es nicht behaupten, dieselbe Abstraktion zu implementieren.

1

Denken Sie an die Arbeit, die Sie aufrufen müssen, und an die Entfernung, von der Sie gerade codieren. Da gibt es ein Spektrum; Ihre Position darauf stellt die Menge an Arbeit dar, die Sie tun müssen, um diese Funktionalität aufzurufen.

Abstraktionen verschieben diese Position näher an den Code, den Sie schreiben. Wenn Sie beispielsweise einen Webdienst aufrufen müssen, können Sie entweder den aufrufenden Code direkt an der Stelle schreiben, an der Sie ihn verwenden müssen, oder 2) diese Details hinter eine Abstraktion (z. B. eine Schnittstelle) stellen.

In diesem Fall bringt Sie # 1 näher zum Web-Service auf dem Spektrum, während # 2 Sie näher an Ihre Arbeit bringt. Abstraktion kann gesagt werden, um ein Maß dafür zu sein, wie weit Sie Ihren Verstand strecken müssen, um die Arbeit zu verstehen, die Sie tun müssen.

Dies bedeutet, dass jede Arbeit abstrahiert werden kann, so dass sie "näher" an dem Code ist, der sie benutzt. Wenn beide Seiten einer Operation von Abstraktionen abhängen, werden sie beide leichter zu verstehen, und keine der beiden Seiten muss Wissen über die Kluft zwischen ihnen haben - das ist die Aufgabe der Abstraktion.

Wow, das war abstrakt.

3

Ein interessanter Fall, in dem eine Abstraktion von Details abhängt, ist, wenn Sie eine Schnittstelle definieren, die von IDisposable erbt.Werfen Sie einen Blick auf die folgende Abstraktion:

public interface ICustomerRepository : IDisposable 
{ 
    Customer GetById(Guid id); 
    Customer[] GetAll(); 
} 

Hinweis: IDisposable ist eine Schnittstelle, die spezifisch für .NET, aber Sie können Ihre Schnittstelle, die eine Dispose Methode selbst statt erben von einer solchen Schnittstelle leicht vorstellen.

Es könnte für die ICustomerRepositoryIDisposableIDisposable geeignet aussehen. Auf diese Weise kann jeder Aufrufer das Repository entsorgen, und auf diese Weise kann die Implementierung die intern verwendete Verbindung oder Arbeitseinheit entsorgen.

Die Schnittstelle ist jedoch jetzt mit einer bestimmten Implementierung im Hinterkopf geschrieben, da es nicht offensichtlich ist, dass alle ICustomerRepository Implementierungen alle Ressourcen bereinigen müssten. Die Schnittstelle verliert daher die Implementierungsdetails und verletzt somit das Dependency Inversion-Prinzip.

Verwandte Themen