java 仅使用静态方法对类进行依赖注入?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15599564/
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
Dependency injection on class with only static methods?
提问by Phil K
I have a set of API classes which contain only static methods and a single private constructor so they cannot be instantiated. However, I would like a third party developer to be able to modify the behaviour of the API's to suit their needs.
我有一组只包含静态方法和一个私有构造函数的 API 类,因此它们不能被实例化。但是,我希望第三方开发人员能够修改 API 的行为以满足他们的需要。
This is the solution I have so far (dependency injection via static setter method). This is the public API class that the developer would use. As you can see, it has a dependency on StaticApiImpl
.
这是我到目前为止的解决方案(通过静态 setter 方法进行依赖注入)。这是开发人员将使用的公共 API 类。如您所见,它依赖于StaticApiImpl
.
public class StaticApi {
private static StaticApiImpl impl = new StaticApiImpl();
private StaticApi() {}
public static void setImpl(StaticApiImpl impl) {
StaticApi.impl = impl;
}
public static void doThing() {
impl.doThing();
}
}
This is the default API implementation as coded myself.
这是我自己编码的默认 API 实现。
public class StaticApiImpl {
public void doThing() {
System.out.println("Do thing the default way.");
}
}
This is a hypothetical extended version of the default implementation that a third party might write:
这是第三方可能编写的默认实现的假设扩展版本:
public class MyCustomStaticApiImpl extends StaticApiImpl {
@Override
public void doThing() {
System.out.println("Do thing differently.");
}
}
The developer would then simply inject their dependency via the setter method upon initialisation of their plugin:
然后,开发人员可以在插件初始化时通过 setter 方法简单地注入他们的依赖项:
public void onLoad() throws Exception {
StaticApi.setImpl(new MyCustomStaticApiImpl());
}
My question is: is this the correct way of doing it? Is there perhaps some design pattern dedicated to cases such as this that I have not heard of?
我的问题是:这是正确的做法吗?也许有一些设计模式专门用于我没有听说过的这种情况?
采纳答案by Blake
What you are setting up here is a factory pattern with the ability for clients to configure which implementation the factory returns. That is fine, but there are a couple of things that you need to do differently.
您在这里设置的是一个工厂模式,客户端可以配置工厂返回的实现。这很好,但是您需要以不同的方式做一些事情。
- Rename
StaticApi
toStaticApiFactory
. This will make its role more clear and avoid a naming conflict with the next parts. - Remove the
public static void doSomething()
method. There's no need to redefine all of your API methods as static methods. Since that is a factory class, all you need instead is a method to get the current implementation, e.g. apublic static StaticApi getInstance()
method that returns the implementation that has been set viasetImpl()
. - Create an interface
StaticApi
that defines the contract of the APIs behavior. The factory class should then allow the clients tosetImpl(StaticApi)
. - Now anyone that needs to use the StaticApi can get a reference via
StaticApiFactory.getInstance()
.
- 重命名
StaticApi
为StaticApiFactory
. 这将使其作用更加明确,并避免与接下来的部分发生命名冲突。 - 删除
public static void doSomething()
方法。无需将所有 API 方法重新定义为静态方法。由于那是一个工厂类,您需要的只是一个获取当前实现的public static StaticApi getInstance()
方法,例如一个返回已通过 设置的实现的方法setImpl()
。 - 创建一个接口
StaticApi
来定义 API 行为的契约。然后,工厂类应该允许客户端setImpl(StaticApi)
. - 现在任何需要使用 StaticApi 的人都可以通过
StaticApiFactory.getInstance()
.
回答by Athlan
The best solution for your 3rd party developer will be using the Proxy
pattern.
您的第 3 方开发人员的最佳解决方案是使用该Proxy
模式。
http://en.wikipedia.org/wiki/Proxy_pattern
http://en.wikipedia.org/wiki/Proxy_pattern
Setting the implementation object as instance is not great solution.
将实现对象设置为实例并不是很好的解决方案。