Frage

Ich stamme aus einer C ++ Hintergrund Ich habe die Komplexität des Java zu meistern Welt und ihre Rahmenbedingungen. Mit Blick auf die Federrahmen für DI Ich bin fällt es schwer, zu glauben, dass ich jede Setter-Funktion machen müssen die für DI Öffentlichkeit unterliegen. Nicht, dass Anforderung brechen die Prinzip der Information Hiding?

Natürlich will ich Frühling in der Lage sein einige private Teile meiner einzustellen Klassen, aber ich will sicher nicht jede Client-Klasse zu tun, um die Lage sein, das gleiche.

Was bin ich hier fehlt?

War es hilfreich?

Lösung

Wenn Sie Code-Schnittstellen , müssen Sie nur Setter auf den Implementierungen belichten. Wie Sie die Schnittstellen in andere Teile des Systems zu injizieren, können sie die Details der Implementierung oder Zustand der Objekte nicht zugreifen können.

Andere Tipps

ich mit Ihrem Punkt einig - das ist, warum ich Konstruktor Injektion bevorzugen.

Sie (können) müssen einen Setter machen, die die Außenseite von einigen Ihrer internen Details informieren, aber es gibt keine Notwendigkeit, einen Getter zu machen. Sie sind also enthüllt einige Informationen, aber nicht wirklich zu viel; es ist nicht wirklich nützlich für alles andere als den vorgesehenen Zweck.

Darüber hinaus würde ich nur empfehlen Anmerkungen und @Autowired verwenden, wobei in diesem Fall brauchen Sie keine öffentlichen Setter zu machen.

Wenn Sie Feder verwenden Anmerkungen (@Autowired) Sie können DI private Mitglieder.

Wenn Sie sich für lose Kopplung gehen und (Einheit) Testbarkeit meiner Ansicht Federn DI ausbricht Informationen, die nicht ausgeblendet werden sollen.

Ich hatte im Grunde die gleiche Frage hier:

Encapsulation im Zeitalter von Frameworks

Ich denke, die Antwort könnte Konstruktor Injektion sein. Setzen Sie Ihre Eigenschaften mit Setter macht es wirklich schwer, etwas zu ecapsulate und gutes Objekt Zustand zu halten.

Nie verwendet @Autowired, neige ich dazu, mit Hilfe von Parametern in der Konstrukteurs mag, aber manchmal ist es schwer zu verstehen, was die Parameter bedeuten, besonders wenn Sie viele Parameter haben - in diesem Fall ziehe ich den „Builder“ Ansatz zu verwenden, in Effective Java beschrieben. Der Konstruktor empfängt das Bauobjekt (die Einrichter hat), und baut sich mit ihm. Die injizierten Attribute der Klasse sind endgültig (Unveränderlichkeit), der „Builder“ Klasse enthält Setter aber nicht Getter (es muss nicht, wie wir es als innere Klasse der Klasse deklarieren, die gebaut wird), und keine Setter brauchen werden die gerade für Spring:

<bean id="runnable" class="MyClass">
   <constructor-arg>
     <bean class="MyClass$Builder">
       <property name="p1" value="p1Value"/>
       <property name="p2" value="p2Value"/>
       <property name="p3" value="p3Value"/>
       <property name="p4" value="p4Value"/>
     </bean>
   </constructor-arg>
</bean>

Klasse Code:

public class MyClass {
   private final String p1;
   private final String p2;
   private final String p3;
   private final String p4;
   public MyClass(Builder builder) {
      this.p1 = builder.p1;
      this.p2 = builder.p2;
      this.p3 = builder.p3;
      this.p4 = builder.p4;
   }

   ...

   public static class Builder {
      private String p1;
      private String p2;
      private String p3;
      private String p4;
      public void setP1(String p1) {
         this.p1 = p1;
      }
      ... and so on
   }
}

Ich nehme an, es ist ein Kompromiss. Sie reduzieren Abhängigkeiten fest verdrahtet, aber Sie möglicherweise den Mut Ihrer Implementierung aussetzen. Mit den richtigen Abstraktionen, können Sie das auch reduzieren, aber dann erhöhen Sie die Komplexität der Codebasis (zum Beispiel eine generische „Connection“ haben, die eine LDAP-Verbindung oder eine SQL-Verbindung sein könnte).

Ich persönlich glaube nicht, mit Konstruktor Injektion mit ihm hilft, entweder, weil es konzeptionell ist.

Ich werde prüfen, @Autowire, tho‘.

tj

Ich wollte nur erwähnen, dass ich (versehentlich) veröffentlichte eine allgemeinere Version dieser Frage, und dass es einige weitere Einblicke in die Frage: Injection kommen auf Kosten der Encapsulation Abhängigkeit muss?

Nicht mit dem Punkt einig, dass der Frühling Verkapselung bricht. Auch wenn Sie pojo haben, wo Sie haben bekommen und Satz in der Klasse ausgesetzt und Dritten verbrauchen Ihr Glas, immer noch Chancen, dass Verbraucher von Glas das gleiche tun, die mit der Spring-Bean-Konfiguration möglich ist. (Gilt für jede andere OOPs Sprache)

Frühling bietet gerade Art und Weise, die durch den Code getan werden kann, und dass die Steuerung bewegte aus dem Code (IOC).

Consumer (man denke an anderen Programmierern verwenden Ihre Bibliothek), erstellte Bohne durch die Federkonfiguration, noch Ihr Code Kontrolle hat. Kein Körper hält Sie Eingabe durch den Benutzer (Feder IOC Rahmen auch durch den gleichen Code geht, die von anderer Klasse aufrufen Ihre Setter getan wird) gegeben zu validieren in Setter.

public void setAge(int age) {
 if ( age < 0 ) {
   throw new AppException("invalid age!");
 }
 this.age=age;
}

Und das ist ein weiterer Grund, warum ich Guice bevorzugen;) Beide Guice und Spring JSR 330 DI-Spezifikation implementieren, aber mit Guice kann ich in meine private Instanz Felder spritzen ohne Setter ein Ich mag nicht Konstruktor Injektion wirklich wie es schwieriger, zu Refactoring schien hat. Es ist auch nur mehr Typisierung alot für nicht viel Wert in meiner bescheidenen Meinung nach.

später, Dean

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top