java 服务定位器与依赖注入
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6291331/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Service Locator vs. Dependency Injection
提问by deamon
I'm reviewing code with a lot of statements like this:
我正在带有很多这样的语句的代码:
private SomeInterface x = Locator.getInstance(SomeInterface.class)
I would expect something like
我希望像
private SomeInterface x;
@Inject
public Consumer(SomeInterface x){ // constructor
this.x = x;
}
Is there something wrong with the first approach? Ok, dependencies are not so obvious, but implementations could easily be swapped through configuration of Locator.
第一种方法有什么问题吗?好的,依赖关系不是那么明显,但是可以通过 Locator 的配置轻松交换实现。
回答by planetjones
Martin Fowler wrote an article on DI versus Locators:
Martin Fowler 写了一篇关于 DI 与定位器的文章:
For DI:
- Easier to determine what dependencies a component has - look at constructor.
- Component does not have dependency on Service Locator so there is not a problem if the component is used with a different framework.
- DI may make testing easier but a good Service Locator mechanism will make stubbing equally feasible
Against DI:
- Harder to debug and understand.
- Component cannot request extra services from injector once it had been configured.
对于 DI:
- 更容易确定组件具有哪些依赖项 - 查看构造函数。
- 组件不依赖于服务定位器,因此如果组件与不同的框架一起使用,则不会出现问题。
- DI 可能使测试更容易,但良好的服务定位器机制将使存根同样可行
反对DI:
- 更难调试和理解。
- 组件一旦配置就不能从注入器请求额外的服务。
I personally don't think there's anything inherently bad with the first locator based approach - I guess DI does standardise this though, so if it's available I would use it. All good ideas tend to end up as frameworks at some point, so this has what's happened here. Plus with DI you can take advantage of other annotations, scopes, etc. without having to roll your own code. And the less bespoke code your project uses the better IMO. I'll leave the last word to Fowler though:
我个人认为第一个基于定位器的方法本身并没有什么坏处——我猜 DI 确实对此进行了标准化,所以如果它可用,我会使用它。所有好的想法都会在某个时候最终成为框架,所以这里发生了这样的事情。加上 DI,您可以利用其他注释、范围等,而无需滚动您自己的代码。您的项目使用的定制代码越少,IMO 就越好。不过,我会将最后一句话留给福勒:
The choice between Service Locator and Dependency Injection is less important than the principle of separating service configuration from the use of services within an application.
服务定位器和依赖注入之间的选择不如将服务配置与应用程序中的服务使用分离的原则重要。
回答by adt
First example : x = Locator.getInstance(SomeInterface.class) is looks like Service Locator pattern, and http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspxcheck this article it says Service Locator is an anti-pattern and should be avoided
第一个例子:x = Locator.getInstance(SomeInterface.class) 看起来像 Service Locator 模式,http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx检查这篇文章它说 Service Locator is an anti - 模式,应该避免
And for the second usage its all fine i like Constructor Injection, its smooth fine implementation. But I would like to not to use Attributes ( annotanitons in Java?) cause anytime i might want to change DI container i am using and i dont want to remove an attribute from all classes.
对于第二次使用,一切都很好,我喜欢构造函数注入,它的实现非常流畅。但是我不想使用属性(Java 中的 annotanitons?)因为我可能想更改我正在使用的 DI 容器并且我不想从所有类中删除属性。
回答by pleerock
Service locatorpattern uses a central registry known as the "service locator" which on request returns the information necessary to perform a certain task.
服务定位器模式使用称为“服务定位器”的中央注册表,它根据请求返回执行特定任务所需的信息。
These are the worst sides of Service Locator Design Pattern:
这些是服务定位器设计模式最糟糕的方面:
Things placed in the registry are effectively black boxes with regards to the rest of the system. This makes it harder to detect and recover from their errors, and may make the system as a whole less reliable.
The registry must be unique, which can make it a bottleneck for
concurrent applications.The registry can be a serious security vulnerability, because it allows outsiders to inject code right into an application.
Can't pass dependencies by constructor (as we do in DI pattern) and hard to unit-test
放在注册表中的东西对于系统的其余部分来说实际上是黑匣子。这使得检测错误和从错误中恢复变得更加困难,并且可能使整个系统的可靠性降低。
注册表必须是唯一的,这可能会成为
并发应用程序的瓶颈。注册表可能是一个严重的安全漏洞,因为它允许外部人员将代码直接注入应用程序。
不能通过构造函数传递依赖项(就像我们在 DI 模式中所做的那样)并且难以进行单元测试
And I my opinion using service locator design pattern is acceptable only on top level of your application when your service locator probably will not change
我认为使用服务定位器设计模式仅在您的应用程序的顶层是可以接受的,而您的服务定位器可能不会改变
回答by ddewaele
There's nothing "wrong" as such with the service locator pattern,
服务定位器模式没有任何“错误”,
In this particular case, the one major argument in favor of DI would be testability.
在这种特殊情况下,支持 DI 的一个主要论据是可测试性。
Without a doubt, DI allows for better unit testing. The static getInstance method on Locator makes it more difficult to test in isolation.
毫无疑问,DI 允许更好的单元测试。Locator 上的静态 getInstance 方法使得单独测试变得更加困难。