Ist für eine TypeLiteral eine gute oder schlechte Übung in Google Guice

8

Google Guice verwendet new TypeLiteral<C<T>>() {} , um die Tatsache zu umgehen, dass wir C<T>.class nicht verwenden können.

Nun gilt Folgendes:

%Vor%

Stellen Sie sich jedoch ein anderes Szenario vor. Wir haben eine generische Schnittstelle, die wir injizieren wollen, und die Implementierung, die wir haben, wird von einer generischen Klasse bereitgestellt.

Guice ermöglicht es Ihnen, dies folgendermaßen zu tun:

%Vor%

Eine andere Möglichkeit wäre, MyGenericClass folgendermaßen zu erweitern:

%Vor%

und binden Sie es dann so:

%Vor%

Wenn MyGenericInterface viel injiziert wird (wenn auch mit verschiedenen Typen), und jedes Mal, wenn ich es injiziere, benutze ich MyGenericClass, der letztere Ansatz führt zu übermäßigem Code. Daher neige ich dazu, das Erste zu benutzen.

Ich wäre sehr gespannt darauf, die Meinung anderer Leute über die Verwendung eines TypeLiterals in der tO-Klausel einer Guice-Bindung zu hören. Ich befürchte, dass ich ein wenig zu kurz komme und sehe daher die Tücken dieses Ansatzes nicht.

    
velocipedist 26.04.2012, 10:28
quelle

2 Antworten

2

In diesem Fall erscheint mir die Verwendung von TypeLiteral für die generische Implementierung viel besser.

Lass es mich so ausdrücken: "Wäre die Unterklasse MyTypedClass vorhanden, wenn du nicht Guice benutzt hättest?". Eine wesentliche Richtlinie von Guice ist: Sie sollten Ihre Implementierungsklassen nicht so anpassen müssen, dass sie in das DI-Framework passen (naja, mit Ausnahme von Dingen wie der @Inject Annotation).

Und was profitieren Sie von der Unterklasse der Beton-noch-generischen Klasse? Ein großer Verlust ist, dass Sie den Konstruktor von MyGenericClass in allen Unterklassen duplizieren müssen. Alles in allem scheint es ein zusätzlicher Code ohne viel Gewinn zu sein.

Alles in allem ist mit der Verwendung von TypeLiteral generell nichts falsch. Und wenn es im .to(...) -Anteil der Bindungsklausel ist (im Gegensatz zu bind(...) , wird es nicht einmal den öffentlich sichtbaren Teil der Bindungen von Module beeinflussen, also glaube ich nicht, dass es viel zu tun gibt sich Sorgen machen.

    
Andrew McNamee 09.06.2012 00:01
quelle
1

Es gibt normalerweise zwei Szenarien:

  1. Sie möchten alle Implementierungen von MyGenericInterface an MyGenericClass binden
  2. Sie möchten die Implementierung von MyGenericInterface base an ihren Typ binden

Für das erste Szenario wird bind(MyGenericInterface).to(MyGenericClass); ausreichen, einfacher und einfacher zu verstehen.

Im zweiten Szenario müssen Sie die Implementierung einer bestimmten Klasse an eine bestimmte Implementierung binden, wobei TypeLiteral ins Spiel kommt.

Außerdem ist der Code in Ihrer Frage nicht klar, ob T eine tatsächliche Klasse oder ein generischer Typ ist. Wenn es ein generischer Typ ist,

bind(new TypeLiteral<MyGenericInterface<T>>() {}).to(new TypeLiteral<MyGenericClass<T>>() {});

und

MyTypedClass extends MyGenericClass<T>

wird nicht kompiliert, da einige tatsächliche Klassen nicht bereitgestellt werden.

    
wyz 01.06.2012 07:22
quelle