Java 服务定位器与依赖注入
我正在用很多这样的语句来检查代码:Java 服务定位器与依赖注入,java,dependency-injection,factory-pattern,Java,Dependency Injection,Factory Pattern,我正在用很多这样的语句来检查代码: private SomeInterface x = Locator.getInstance(SomeInterface.class) 我期待着类似的事情 private SomeInterface x; @Inject public Consumer(SomeInterface x){ // constructor this.x = x; } 第一种方法有问题吗?好的,依赖关系不是很明显,但是可以通过配置定位器轻松地交换实现。第一个示例: get
private SomeInterface x = Locator.getInstance(SomeInterface.class)
我期待着类似的事情
private SomeInterface x;
@Inject
public Consumer(SomeInterface x){ // constructor
this.x = x;
}
第一种方法有问题吗?好的,依赖关系不是很明显,但是可以通过配置定位器轻松地交换实现。第一个示例:
getInstance(SomeInterface.class)看起来像服务定位器模式,检查本文,它说服务定位器是一种反模式,应该避免
对于第二个用法,它非常好,我喜欢构造函数注入,它平滑而精细的实现。但是我不想使用属性(Java中的注释),因为任何时候我都可能想更改我正在使用的DI容器,并且我不想从所有类中删除属性。Martin Fowler写道:
对于DI:
- 更容易确定组件具有哪些依赖关系-查看 构造器
- 组件不依赖于服务定位器,因此不存在 如果组件与一起使用,则会出现问题 一个不同的框架
- DI可能使测试更容易,但一个好的服务定位器机制将使测试更容易 使存根同样可行
- 更难调试和理解
- 组件一旦启动,就无法从injector请求额外服务 已配置
- 放置在注册表中的东西实际上是带有 关于系统的其余部分。这使得它更难检测和识别 从错误中恢复,并可能使整个系统更少 可靠
- 注册表必须是唯一的,这会使它成为
并发应用程序 - 注册表可能是一个严重的安全漏洞,因为它 允许外部人员将代码直接注入到应用程序中
- 无法通过构造函数传递依赖项(就像我们在DI模式中所做的那样),并且很难进行单元测试
我认为只有在应用程序的顶层使用服务定位器设计模式是可以接受的,因为您的服务定位器可能不会更改。
@Inject
是由@deamon在Java中标准化的,我认为这只是CrazyBob的DI注释。我不知道它被认为是语言标准。谢谢你的信息。另外:定义在,和。现在维护在as。不仅仅是单元测试。马克·希曼(MarkSeemann)对此做了非常清楚的描述:。他想避免这种哲学讨论:)“反模式”是一种被过度使用的说法。我个人也支持DI,但我不会在代码审查期间将其标记为反模式。几年前,我在一个项目中引入了IoC(以服务定位器模式的形式),以允许该团队开始编写测试。这是一个很好的开始,因为根本无法进行测试。但是现在,两年多之后,到处都是这种模式而不是使用DI是一种真正的痛苦。所以对我来说,这不再是哲学。我去过那里,我经历过,这都是我的错。这些天来,我尽力尖叫,帮助别人避免犯我犯的错误。