WikiDer > Abhängigkeitsspritze
Abhängigkeitsspritze ist ein fortgeschrittener Designmuster von dem Informatik das macht es möglich Klassenlose verlinken. Das bedeutet, dass sie ohne diese Beziehung Daten austauschen können schwer (in dem Quellcode) Ist repariert; zumindest nicht von den Programmierern dieser (beiden) Klassen. Traditionell passiert dies oft, was es schwierig macht, diese Kurse zu Wiederverwendung sein.
Manchmal wird „Dependency Injection“ als eine spezielle Form der „Inversion of Control“ angesehen, die erstmals von Martin Fowler beschrieben wurde.[1]
Benutzen
Obwohl dieses Muster im Konzept recht einfach ist, erfordert es von den Entwicklern Disziplin, es korrekt auszuführen. Dies liegt auch daran, dass mehrere beliebte Programmiersprachen unterstützen dieses Muster nicht gut. Es gibt verschiedene Erweiterungen für verschiedene Sprachen, um Programmierer zu unterstützen. springen (vor dem Java) ist wohl die bekannteste.
Harte Kopplungen sind in der Praxis oft einfacher zu programmieren, insbesondere bei kleinen Programmen, bei denen die Nachteile (von harten Kopplungen) gering sind. Dies macht es für unerfahrene Programmierer manchmal schwierig, dieses „bessere“ Muster zu erlernen.
Beispiel
Ein Beispiel für lose verlinken, außerhalb der Computerindustrie, ist der Anschluss eines (Kabel-)Schalters und einer Lampe. Um das Licht ein- und auszuschalten, müssen der Schalter und die Lampe verbunden werden. In der Praxis macht das jeder mit einem Stück Schnur. Wichtig ist, dass sowohl die Lampe als auch der Schalter die gleiche (Standard-)Kupplung haben: die Klemmleiste. Mit einer einfachen Bedienung (Anziehen einer Schraube) wird die Verbindung hergestellt, ohne dass die Lampe oder der Schalter verändert oder eingestellt werden müssen. Der Link ist lose: Weder die Lampe noch der Schalter sind speziell für die Verwendung mit dem anderen entwickelt worden. Es können auch eine andere Lampe (anderer Marke oder Typs), mehrere Lampen oder ein oder mehrere (andere) Schalter verwendet werden.
Vergleichen Sie das mit einer Stehlampe mit eingebautem Schalter: der steuert auch die Lampe, aber der Link ist es nicht schwer. Es ist kaum möglich, einen anderen Schalter zu verwenden.
Programmier-Herausforderung
Die gleiche Herausforderung sehen wir beim Programmieren: Einerseits gibt es separate Teile (Klassen), die zusammenarbeiten müssen. Andererseits wollen wir diese Komponenten unabhängig voneinander entwickeln, damit sie an möglichst vielen Stellen eingesetzt werden können.
Mittels „Dependency Injection“ ist es möglich, die Teile getrennt voneinander zu entwickeln und anschließend zu verbinden. Es gibt mehrere Möglichkeiten, dies zu erreichen, ein guter Programmierer kann selbst Code dafür schreiben oder ein Framework (oder Tool) verwenden, das dies für Sie erledigt.
In allen Fällen enthält der Programmcode (das Objekt) Code-Bits (Attribute), die wie im obigen Beispiel dem Klemmenblock entsprechen. Aber auch Funktionen, die dieses Attribut effektiv einstellen können (Anziehen der Schraube). Der Rest des Codes verwendet dieses Attribut, das auf ein anderes Objekt verweist (etwa die Zeichenfolge im Beispiel).
Codebeispiel
Das obige Schalter-Lampen-Beispiel kann fast sofort in Code umgewandelt werden. Wir brauchen zwei Klassen (Lamp, Switch) und eine Schnittstelle oder ein Protokoll (OnOff). Da viele Sprachen letzteres nicht unterstützen, verwenden wir dafür eine Klasse: IAanuit. Dies wird im folgenden Beispiel nicht verwendet.
Der folgende Beispielcode ist geschrieben in Python. Es kann leicht in andere Programmiersprachen konvertiert werden.
OBEN=1NIEDER=2KlasseIOnOff(Objekt):defAuf(Absender):bestehendefvon(Absender):bestehenKlasseLampe(Objekt):# Entspricht IOnOffdef__drin__(selbst):selbst.ist an=FalschdefAuf(selbst,Absender):selbst.ist an=wahrdrucken„Das Licht geht an“defvon(selbst,Absender):selbst.ist an=Falschdrucken'Das Licht geht aus'KlasseSchalter(Objekt):def__drin__(selbst,Auslauf):# Outlet ist der Kern der Dependency Injection – siehe Textselbst.Status=keiner# Der Status in (hier) ist zunächst unbekanntselbst.Auslauf=Auslauf# Steckdose bezieht sich (zB) auf die Lampe -- Steckdose muss dem IOnOff-Protokoll entsprechendefoben(selbst):wennselbst.Status!=OBEN:selbst.Status=OBENselbst.Auslauf.Auf(Absender=selbst)# Dies ruft die Methode to() von self.outlet aufdefNieder(selbst):wennselbst.Status!=NIEDER:selbst.Status=NIEDERselbst.Auslauf.von(Absender=selbst)# Schaltet aus (z. B. eine Lampe)defMain():l=Lampe()so=Schalter(l)# ...so.oben()# Das Licht schaltet sich einso.Nieder()so.Nieder()Main()In diesem Python-Beispiel sind die Klassen Lamp und Switch völlig unabhängig voneinander, sie teilen sich nur das informelle IOnOff-Protokoll. Der Switch sendet die Nachrichten und die Lampe kann sie dann empfangen und verarbeiten. Die Instanzen werden nur in der Hauptroutine (normalerweise in einer anderen Datei) miteinander verknüpft. In diesem einfachen Beispiel geschieht dies durch die Übergabe einer Instanz (Referenz) beim Erstellen des Objekts. In anderen Beispielen geschieht dies später, beispielsweise mit einer 'setOutlet()'- oder 'connectSwitch()'-Methode der Switch-Klasse.
Der Kern der Lösung ist das Attribut Auslauf in der Klasse 'Switch'. Dies ist eine Referenz (Referenz, Zeiger) auf ein anderes Objekt. Nachdem dieser 'Ausgang' gesetzt wurde, können Nachrichten an dieses Objekt (zB eine Lampe) gesendet werden. Beachten Sie jedoch, dass der Switch (Implementierungscode) keine Möglichkeit hat, zu erkennen, dass es sich um eine Lampe handelt. Der Switch kann somit auch andere Objekte steuern, sofern diese dem IOnOff-Protokoll entsprechen.
Hinweis: In einigen Sprachen, z. B. in Ziel c, kann explizit gemacht werden, dass das angesprochene Objekt dem korrekten Protokoll (hier IAanUit) entsprechen muss, in Python ist dies nicht möglich.
Dieses Beispiel zeigt auch eine subtilere Form der Dependency Injection: den sender-Parameter beider Methoden im IOnOff-Protokoll. Der Schalter gibt sich beim Betrieb der Lampe als Parameter an. Als Ergebnis „weiß“ die empfangende Klasse, was der Sender ist. Und so gibt es einen Link: Der Empfänger kann Nachrichten an den Absender senden. Im obigen Beispiel passiert das nicht, aber es ist einfach einzubeziehen.
Alternativen
- Fabrik (Entwurfsmuster), wird manchmal als besser angesehen, von anderen als vermeidbares Muster in anderen Sprachen als C .