【问题标题】:Choose a concrete implementation at runtime with Java 8使用 Java 8 在运行时选择具体实现
【发布时间】:2015-04-16 16:15:12
【问题描述】:

在选择要实例化的实现/子类时,我不清楚将 if/switch 放在哪里,特别是考虑到现在接口可以具有静态方法时。

假设我有一个服务、一个由接口定义的类型和几个实现。我想最好不要把这个逻辑放在服务中,而是有工厂方法。但它应该像this answer 中所建议的那样放在接口中还是放在另一个具有参数到类型映射的类中?

把它放在界面中对我来说似乎很自然:

public interface MyInterface
{
    public void doSomething();

    public static MyInterface create(int param)
    {
        if (param == 0)
            return new ImplA();
        else
            return new ImplB();
    }
}

然后只需从服务中调用它:

public class MyService
{
    public void serveMe(int param)
    {
        MyInterface.create(param).doSomething();
    }
}

但是我不知道让接口知道它的实现,或者让父类知道它的子类型是否不好。所以

  1. 我应该把这个逻辑放在哪里?
  2. 如果我选择一个类型的子类,这会改变很多吗?

【问题讨论】:

标签: java inheritance interface-implementation


【解决方案1】:

为此使用Factory。这样您就可以维护single responsibility principle。然而,在我自己的一个项目中,interface 定义了一种方法,该方法确定应该使用这种特定实现的参数类型。多亏了这一点并使用Reflections,整个过程都是自动化的。 Reflections 查找所有实现给定interface 的类,并将其“使用类型”存储在映射中以便快速查找。多亏了这样的解决方案,如果开发人员需要新的实现,他所要做的就是创建它。系统的其他部分不需要进行其他修改,即使在工厂类中也是如此。

Reflections 具有在编译时存储元数据的好功能,因此运行时查找适当的类是一眨眼的功夫

【讨论】:

  • “多亏了这样的解决方案,如果开发人员需要新的实现,他所要做的就是创建它。”。但是他或其他人需要定义选择其中一种实现的标准,对吗?标准在界面中?
  • Yes 和 No - 接口强制实现类通过声明某种方法来提供这样的标准,例如。 getProcessingType。在为新的“ProcessingType”创建实现时,开发人员将在创建它时提供标准。
  • 回到我的问题。你的建议是有一个Factory 类,只有一个静态方法,对吧?
【解决方案2】:

您的问题有很多解决方案,我想您已经知道其中的很多了。

静态工厂方法模式

interface Interface {
    public static Interface create(...);
}

这可行,但是它使接口和实现的分离变得困难。接口必须知道所有可能的实现,并且它不是特别可扩展的。要添加新的实现,您需要更改接口。

工厂模式

GOF 这本书或多或少有点老派:

interface Factory {
    public Interface create(...)
}

这允许您替换工厂(甚至堆栈工厂)。它有——然而——你需要传递工厂对象的缺点。请注意,使用 Java 8,您还可以使用非常轻量级的基于 lambda 的工厂(请参阅https://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html

容器

另一种解决方案,虽然它可能非常重量级,但将对象的构造留给容器框架。在这些情况下,容器提供您的对象工厂。对象的实际类型留给配置。 Spring 和 Java EE 在这方面做了很多工作。还可以结合依赖注入来增加效果。

这些至少是我能想到的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    相关资源
    最近更新 更多