Question

Venant d’un contexte C ++, je dois maîtriser la complexité de Java. monde et ses cadres. En regardant le cadre de printemps pour DI je suis avoir du mal à croire que je dois faire chaque fonction de setter qui sera soumis à DI public. Cette exigence ne rompt-elle pas principe de la dissimulation d'informations?

Bien sûr, je veux que le printemps puisse définir certaines parties privées de mon classes, mais je ne veux certainement pas que chaque classe de client puisse faire le même.

Qu'est-ce qui me manque ici?

Était-ce utile?

La solution

Si vous codez des interfaces , il vous suffit d'exposer les paramètres de configuration sur les implémentations. Lorsque vous injectez les interfaces dans d'autres parties du système, elles ne peuvent pas accéder aux détails de la mise en œuvre ni à l'état des objets.

Autres conseils

Je suis d'accord avec votre argument. C'est pourquoi je préfère l'injection de constructeur.

Vous devez (éventuellement) créer un configurateur, qui informera l’extérieur de certains de vos détails internes, mais il n’est pas nécessaire de créer un getter. Donc, vous révélez certaines informations, mais pas vraiment trop; ce n'est pas vraiment utile pour autre chose que le but recherché.

En outre, je vous recommanderais simplement d'utiliser les annotations et @Autowired, auquel cas vous n'avez pas besoin de créer un séparateur public.

Si vous utilisez des annotations printanières (@Autowired), vous pouvez accéder à des membres privés.

Si vous optez pour un couplage lâche et que, à mon avis, la testabilité (de l'unité) se révèle, les ressorts DI diffusent des informations qu'il ne faut pas masquer.

J'avais essentiellement la même question ici:

Encapsulation à l'ère des frameworks

Je pense que la réponse pourrait être l'injection de constructeur. Exposer vos propriétés à l'aide de setters rend très difficile la possibilité d'écapsuler quoi que ce soit et de conserver un bon état d'objet.

Jamais utilisé @Autowired, j'ai tendance à aimer utiliser des paramètres dans les constructeurs, mais il est parfois difficile de comprendre ce que signifient les paramètres, en particulier si vous avez beaucoup de paramètres. Dans ce cas, je préfère utiliser le "Builder". approche décrite dans Effective Java. Le constructeur reçoit l'objet de construction (qui a des setters) et se construit avec lui. Les attributs injectés de la classe sont finaux (immuabilité), le "Constructeur". la classe contient des setters mais pas des accesseurs (cela n'est pas nécessaire car nous la déclarons comme une classe interne de la classe en cours de construction), et aucun setters ne doit être créé uniquement pour 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>

Code de la classe:

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
   }
}

Je suppose que c'est un compromis. Vous réduisez les dépendances câblées, mais vous exposez potentiellement les entrailles de votre implémentation. Avec les bonnes abstractions, vous pouvez également réduire cela, mais vous augmentez la complexité de la base de code (par exemple, disposer d'une "connexion" générique qui pourrait être une connexion LDAP ou une connexion SQL).

Personnellement, je ne pense pas non plus que l’injection de constructeur y contribue, car c’est plus conceptuel.

Je vais devoir vérifier @Autowire, mais '.

tj

Et c’est une autre raison pour laquelle je préfère Guice;) Guice et Spring appliquent les spécifications JSR 330 DI, mais avec Guice, je peux injecter dans mon instance privée des champs sans régleurs et je n’aime vraiment pas l’injection de constructeur, car il me semblait plus difficile de la refactoriser. C’est aussi beaucoup plus de dactylographie pour peu de valeur à mon humble avis.

plus tard, Dean

scroll top