Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
不';t形弹簧&x27;s依赖注入中断信息隐藏? P>来自C++背景的我必须掌握java的复杂性 世界及其框架。查看DI I的spring框架 发现很难相信我必须使每个setter函数 这将是DI public的主题。这项要求是否违反了规定 信息隐藏原理_Java_Spring_Dependency Injection_Encapsulation - Fatal编程技术网

不';t形弹簧&x27;s依赖注入中断信息隐藏? P>来自C++背景的我必须掌握java的复杂性 世界及其框架。查看DI I的spring框架 发现很难相信我必须使每个setter函数 这将是DI public的主题。这项要求是否违反了规定 信息隐藏原理

不';t形弹簧&x27;s依赖注入中断信息隐藏? P>来自C++背景的我必须掌握java的复杂性 世界及其框架。查看DI I的spring框架 发现很难相信我必须使每个setter函数 这将是DI public的主题。这项要求是否违反了规定 信息隐藏原理,java,spring,dependency-injection,encapsulation,Java,Spring,Dependency Injection,Encapsulation,当然,我希望spring能够设置我的一些私有部分 类,但我当然不希望每个客户机类都能这样做 同样的 我在这里遗漏了什么?我同意你的观点-这就是为什么我更喜欢构造函数注入 您(可能)必须制作一个setter,它将通知外部您的一些内部细节,但无需制作getter。所以你透露了一些信息,但并不是太多;除了它的预期用途之外,它对任何东西都没有真正的用处 此外,我建议您使用注释和@Autowired,在这种情况下,您不需要使用公共setter。如果您使用spring注释(@Autowired),您可以使用

当然,我希望spring能够设置我的一些私有部分 类,但我当然不希望每个客户机类都能这样做 同样的


我在这里遗漏了什么?

我同意你的观点-这就是为什么我更喜欢构造函数注入

您(可能)必须制作一个setter,它将通知外部您的一些内部细节,但无需制作getter。所以你透露了一些信息,但并不是太多;除了它的预期用途之外,它对任何东西都没有真正的用处


此外,我建议您使用注释和@Autowired,在这种情况下,您不需要使用公共setter。

如果您使用spring注释(@Autowired),您可以使用DI私有成员


在我看来,如果你追求松耦合和(单元)可测试性,springs DI会释放出不应该隐藏的信息。

我认为这是一种折衷。您可以减少硬连线的依赖关系,但可能会暴露实现的本质。通过正确的抽象,您也可以减少这一点,但随后会增加代码库的复杂性(例如,拥有一个可以是LDAP连接或SQL连接的通用“连接”)

就个人而言,我认为使用构造函数注入也没有帮助,因为它更具概念性

我必须签出@Autowire,tho


tj

我这里有一个基本相同的问题:


我想答案可能是构造函数注入。使用setter公开属性会使您很难对任何内容进行封装并保持良好的对象状态。

如果您对接口进行编码,则只需在实现上公开setter即可。当您将接口注入到系统的其他部分时,它们无法访问对象的实现细节或状态。

只是想提到,我(无意中)发布了这个问题的一个更通用的版本,它对这个问题有一些进一步的见解:

从未使用过@Autowired,我倾向于在构造函数中使用参数,但有时很难理解参数的含义,特别是如果您有很多参数——在这种情况下,我更喜欢使用有效Java中描述的“构建器”方法。构造函数接收构建对象(具有setter),并使用它构造自身。类的注入属性是final(不变性),“Builder”类包含setter,但不包含getter(不需要,因为我们将其声明为正在构造的类的内部类),并且不需要仅为Spring创建setter:

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

不同意弹簧破坏封装的观点。即使您有pojo,其中的get和set在类中公开,并且第三方使用您的jar,jar的使用者仍然有可能执行与Springbean配置相同的操作。(适用于任何其他OOPs语言)

Spring只是提供了一种可以通过代码完成的方法,并且控制权可以从代码中移出(IOC)

消费者(考虑其他程序员使用您的库),通过spring配置创建bean,但您的代码仍然具有控制权。在setter中,没有任何主体阻止您验证用户提供的输入(SpringIOC框架也会通过与调用setter的其他类相同的代码)

public void setAge(int age) {
 if ( age < 0 ) {
   throw new AppException("invalid age!");
 }
 this.age=age;
}
public void设置(int-age){
如果(年龄<0){
抛出新的AppException(“无效年龄!”);
}
这个。年龄=年龄;
}

这也是我喜欢Guice的另一个原因;)Guice和Spring都实现了JSR330 DI规范,但是有了Guice,我可以在没有设置器的情况下注入到我的私有实例字段中。我真的不喜欢构造函数注入,因为它似乎更难重构。在我看来,它只是更多的打字,没有多少价值

后来,,
Dean

+1关于构造函数注入。将依赖关系表达得更强,并且不再需要“有趣的”settersconstructor注入++:创建对象后,它必须准备好使用并处于一致状态。类的正确操作可能不需要所有属性。在这种情况下,我总是通过setters@oxbox,这表明了两种样式之间的确切区别。只要可能,支持注释是一件好事。现在我自己也在尝试跳转,但很难打破这种XML习惯。这个答案意味着“向接口编码”意味着每个类都必须实现一个单独的接口。这不是GoF书中描述的原则的意思。实际上,它只适用于您需要或已经有两种不同对象类型的情况,一种用于抽象(接口),另一种用于该抽象的一种实现。我认为您可能会发现,在公共Spring应用程序中需要相互注入的类是服务类,例如
Dao
s等。我发现其中很多可能有替代实现,当您有多个实现时,“代码到接口,而不是实现”原则确实适用。但是,在没有明确上下文的情况下说“如果您为接口编写代码…”之类的话会产生误导,并且很容易被经验不足的开发人员误解。在我看来,过度使用单独的接口会造成很大的危害。什么危害?诚然,在代码库膨胀的情况下,从迫使您思考正在解决的问题中存在哪些抽象的角度来看,从接口而不是实现开始是积极的
public void setAge(int age) {
 if ( age < 0 ) {
   throw new AppException("invalid age!");
 }
 this.age=age;
}