Warum bevorzugen Template-Methode gegenüber Dependency-Injektion?

8

Ich habe Design Patterns gelesen, von Gamma et al. Ich habe eine Frage bezüglich der Template-Methode im Vergleich zu Dependency Injection.

Mit der Vorlagenmethode können Sie "Vorlagen" -Klassen mit Richtlinien erstellen, die Alternativen für erforderliche Aktionen oder Berechnungen bereitstellen. Anstatt also eine Richtlinie aus mehreren Alternativen auszuwählen und diese Richtlinie in die Klasse zu schreiben, erlauben Sie dem Benutzer der Klasse, die gewünschte Alternative anzugeben.

Es klingt alles sehr vernünftig für mich. Aber ich habe ein bisschen von einer konzeptuellen Mauer getroffen.

Wenn Sie eine Klasse mit einem Richtlinienobjekt instanziieren, muss das Richtlinienobjekt eine abstrakte Schnittstelle implementieren. Der Programmierer kann dann verschiedene Richtlinien schreiben, die alle ohne Fehler in die Klasse kompilieren, da die Richtlinien die Schnittstelle implementieren. Die Klasse, die die Richtlinien verwendet, ist für die Richtlinienschnittstelle und nicht für die Implementierung codiert.

Wenn Sie eine abstrakte IPolicy für diese Richtlinienobjekte definieren möchten, verwenden Sie einfach Dependency Injection und übergeben Sie die IPolicy on construction?

Kann jemand etwas darüber sagen, warum Sie die Template-Methode der Dependency-Injektion vorziehen würden?

    
Robinson 15.11.2011, 09:56
quelle

3 Antworten

14

Was die "Schablonenmethode" (und nicht das Entwurfsmuster) betrifft, könnte das folgende Beispiel mit den Vor- und Nachteilen helfen und entscheiden, was zu tun ist. Das Beispiel besteht darin, einen ausführlichen Modus einer Bibliothek zu erstellen, der das Debuggen / Entwickeln unterstützen soll.

Mit Vorlagen

%Vor%

Der Bibliotheksbenutzer kann dann schreiben:

%Vor%

Der Vorteil dieses Codes ist, wenn der Benutzer nicht möchte, dass der Code gedruckt wird, dann verschwinden die Aufrufe von dont_print::print(msg) vollständig aus dem Code (leere statische Klassen werden einfach entfernt). Solche Debug-Meldungen können dann in sogar leistungskritische Bereiche eingegeben werden.

Der Nachteil von Vorlagen besteht darin, dass Sie Ihre Richtlinie vor dem Kompilieren festlegen müssen. Sie müssen auch die Funktions- / Klassensignatur Ihrer Templates ändern.

ohne Vorlagen

Das obige könnte natürlich mit etwas wie:

gemacht werden %Vor%

Der Vorteil besteht darin, dass Sie Druckertypen an Ihre Klassen und Funktionen übergeben und zur Laufzeit ändern können (dies kann für einige Anwendungen sehr nützlich sein). Die Kosten bestehen jedoch darin, dass immer ein Aufruf an die virtuelle Funktion erfolgt, so dass der leere dont_print geringe Kosten verursacht. Dies kann für performance-kritische Regionen akzeptabel sein oder auch nicht.

    
Tom 15.11.2011, 10:25
quelle
6

Erstens, wie der Begriff "Phresnel" bereits erwähnt hat, ist das Template-Method-Muster nicht eine Vorlage im modernen Sinne. Lesen Sie es erneut, es verwendet Laufzeit-Polymorphismus, um das gleiche Ziel zu erreichen, für das die STL-Algorithmen Kompilierzeit-Polymorphismus (Funktionsschablonen) verwenden.

Zweitens sind alle Arten von Polymorphismen in gewisser Weise Abhängigkeitsinjektionen. Das heißt, der Aufrufer führt den Algorithmus in den konkreten Typ ein, auf den er einwirkt. Daher ist die Frage im Allgemeinen nicht, ob Sie die Abhängigkeitsinjektion statt eines anderen Musters verwenden könnten oder nicht. Stattdessen zeigt das Muster eine nützliche Methode zur Strukturierung Ihres Codes, um die Abhängigkeitsinjektion zu verwenden.

Wenn Ihre "injected dependency" ein Template-Typ-Parameter ist, verwendet der Algorithmus die Duck-Typisierung und Sie müssen keine abstrakte Schnittstelle implementieren: schreiben Sie einfach Methoden mit der erwarteten Signatur.

    
Useless 15.11.2011 10:12
quelle
2

Die "Vorlagenmethode" in Ihrem Fall (nicht mit dem Vorlagenmethodenmuster ) verwechseln, oder lassen Sie uns Nennen Sie es "statische Abhängigkeitsinjektion", würde die Notwendigkeit für virtuelle Funktionen vermeiden. Sie erhalten Leistung vor allem, indem Sie dem Compiler mehr und konkreteres Wissen geben und ihm somit eine bessere Gelegenheit für Optimierungen geben. Die Klassen werden statischer und die Typsicherheit wird erhöht.

Die Klassengröße kann potenziell schrumpfen (keine oder reduzierte Notwendigkeit, Zeiger zu speichern).

Das alte Sprichwort:

  

Bezahlen Sie nicht für das, was Sie nicht verwenden.

gilt hier. Wenn Sie keine virtuellen Schnittstellen benötigen, können Sie mithilfe von Vorlagen vermieden werden, ohne dass die Flexibilität beeinträchtigt wird.

    
Sebastian Mach 15.11.2011 10:04
quelle