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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 20:12:25  来源:igfitidea点击:

Dependency injection on class with only static methods?

javadesign-patternsdependency-injection

提问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.

您在这里设置的是一个工厂模式,客户端可以配置工厂返回的实现。这很好,但是您需要以不同的方式做一些事情。

  1. Rename StaticApito StaticApiFactory. This will make its role more clear and avoid a naming conflict with the next parts.
  2. 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. a public static StaticApi getInstance()method that returns the implementation that has been set via setImpl().
  3. Create an interface StaticApithat defines the contract of the APIs behavior. The factory class should then allow the clients to setImpl(StaticApi).
  4. Now anyone that needs to use the StaticApi can get a reference via StaticApiFactory.getInstance().
  1. 重命名StaticApiStaticApiFactory. 这将使其作用更加明确,并避免与接下来的部分发生命名冲突。
  2. 删除public static void doSomething()方法。无需将所有 API 方法重新定义为静态方法。由于那是一个工厂类,您需要的只是一个获取当前实现的public static StaticApi getInstance()方法,例如一个返回已通过 设置的实现的方法setImpl()
  3. 创建一个接口StaticApi来定义 API 行为的契约。然后,工厂类应该允许客户端setImpl(StaticApi).
  4. 现在任何需要使用 StaticApi 的人都可以通过StaticApiFactory.getInstance().

回答by Athlan

The best solution for your 3rd party developer will be using the Proxypattern.

您的第 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.

将实现对象设置为实例并不是很好的解决方案。