Java Factory 根据传递的类型创建参数化的泛型

标签 java generics factory

我宿醉了,今天 Action 特别慢。

我想将 Intent 的子类传递给某个工厂,并返回 Handler<? extends Intent> ,其中参数化类型与传递给工厂的参数类型匹配。

public interface HandlerFactory
{
    <I extends Intent> Handler<I> build(I intent);
}

我正在努力实现这一点。我不想用一个令人讨厌的 if/else 检查所有不同类型的 Intent ,然后为每个类型创建适当的 Handler<> ,并根据我们最终所处的条件 block 进行转换。我不想使用访问者模式的一些变体,因为那时我的工厂与 Intent/Handler<? extends Intent>每个子类耦合。更“可插入”的东西似乎是可取的。

如何在没有一些肮脏的类型转换的情况下实现这个?下面的简化情况无法编译,因为虽然 OrgHandler 实现 Handler<OrgIntent> ,但编译器不知道传递的 Intent ( I ) 是 OrgIntent 而不是任何其他子类。

public class SimpleHandlerFactory implements HandlerFactory
{    
    @Override
    public <I extends Intent> Handler<I> build(I intent)
    {
        // Filthy conditional that I want to avoid
        if(intent instanceof OrgIntent)
        {
            // Cast seems wrong
            return (Handler<I>) new SimpleOrgHandler(intent);
        }
        else if(intent instanceof SomeOtherIntent)
        {
            ...
    }
}

更新

客户端代码有List<Intent>并且并不真正关心子类型;它需要构建一个 List<Handler> (我想我需要在那里进行原始类型抑制),然后对每个函数调用一个方法。

List<Intent> intents = orderedIntentBuilder.getOrderedIntents(declaration);
for(Intent intent : intents)
{
    Handler<Intent> handler = handlerFactory.build(intent);
    handler.resolve(someUnimportantArg);
}

最佳答案

我看到这里存在循环依赖的可能性。您希望从 Intent 转到 Handler,而 Intent 不应该知道 Handler,并且 Handler 已经了解 Intent

人们可能想知道为什么一个类需要一个专用处理程序,那么处理程序功能不应该由类本身的一部分实现吗?


任何方法,一种简单的方法是向 Intent 添加一个 getHandler 方法:

interface Handler<T extends Intent> {}

interface Intent {
    Handler<?> getHandler();
}

class OrgIntent {    
    @Override
    public Handler<OrgIntent> getHandler() {
        return new SimpleOrgHandler(this);
     }
}

...
List<Intent> intents = orderedIntentBuilder.getOrderedIntents(declaration);
for(Intent intent : intents)
{
    Handler<?> handler = intent.getHandler();
    handler.resolve(someUnimportantArg);
}

这确实在 IntentHandler 之间创建了循环依赖关系。你可能会同意,但还有一种方法可以解决这个问题。


通过将处理程序操作的数据“模型”提取到第三个类中:

interface IntentModel {...}

Handler 现在在此模型上运行,而不是 Intent 本身。

class OrgIntent {    
    @Override
    public Handler<OrgIntentModel> getHandler() { // <-- Handler<OrgIntentModel>
        return new SimpleOrgHandler(this.model); // passing only model
    }
}

这会创建依赖项:

Intent -> IntentModel
Intent -> Handler
Handler -> IntentModel

在这种情况下,您可能希望将 Handler 功能与 IntentModel 合并。那里不会有循环依赖,因为模型只对自身运行。

关于Java Factory 根据传递的类型创建参数化的泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37989174/

相关文章:

Java 8 - 向需要泛型类型的方法提供原始类型参数会导致其返回类型被删除

Java:类似于 Java 中的 ord PHP 的方法

java - 升级 Android Studio NDK : CMAKE_C_COMPILER and CMAKE_CXX_COMPILER not set 后出错

javascript - 在工厂类中实现继承,而无需在 Javascript 中复制代码

java - 我的控制台说它终止了一个文件,但它从未在控制台中写入我需要的单词

java - 如何在泛型类中使用 Enum 的静态函数?

generics - 特征的泛型类型和泛型关联类型有什么区别?

java - 在 “Integer cannot be converted to E[]”中遇到错误,但在其他地方可以使用?

java - 使用FactoryBean初始化的Bean接收FactoryBean而不是它创建的Obect

dart - 如何在 Flutter 中创建基工厂并在子类上覆盖它