Java泛型抽象工厂问题

Woj*_*zyk 5 java generics design-patterns abstract-factory

我正在努力做这项工作:

public abstract class MapperFactory<M extends TaskMapper<? extends Message, ? extends Message, ? extends TaskForm>> {

    public static <M extends TaskMapper<? extends Message, ? extends Message, ? extends TaskForm>> MapperFactory<M> getMapperFactory(Message msgIn, Message msgOut) {

        if (msgIn.isMyMapper())
            return new MyTaskMapperFactory();

        throw new IllegalStateException("Mapper not found!");
    }

    public abstract TaskMapper<? extends Message, ? extends Message, ? extends TaskForm> getTaskMapper();

    public static class MyTaskMapperFactory extends MapperFactory<MyTaskMapper> {

        @Override
        public TaskMapper<? extends Message, ? extends Message, ? extends TaskForm> getTaskMapper() {
            return new MyTaskMapper();
        }

    }
}

public interface TaskMapper<I extends Message, O extends Message, F extends TaskForm> {

    public F fillForm(I msgIn, O msgOut, F taskForm);

    public O fillMsgOut(F taskForm);
}

public class MyTaskMapper implements TaskMapper<IncomingMessage, OutgoingMessage, MyTaskForm > {

    public MyTaskForm fillForm(IncomingMessage msgIn, OutgoingMessage msgOut,
            MyTaskForm taskForm) {
        return null;
    }

    public OutgoingMessage fillMsgOut(MyTaskForm taskForm) {
        return null;
    }

}
Run Code Online (Sandbox Code Playgroud)

问题是编译错误:

类型不匹配:无法从MapperFactory.MyTaskMapperFactory转换为MapperFactory

在我的MapperFactory中:

if (msgIn.isMyMapper())
            return new MyTaskMapperFactory();
Run Code Online (Sandbox Code Playgroud)

任何想法如何解决此错误?

当然替换:

public static <M extends TaskMapper<? extends Message, ? extends Message, ? extends TaskForm>> MapperFactory<M> getMapperFactory(Message msgIn, Message msgOut) {

        if (msgIn.isMyMapper())
            return new MyTaskMapperFactory();

        throw new IllegalStateException("Mapper not found!");
    }
Run Code Online (Sandbox Code Playgroud)

有:

public static MapperFactory<?> getMapperFactory(Message msgIn, Message msgOut) {

        if (msgIn.isMyMapper())
            return new MyTaskMapperFactory();

        throw new IllegalStateException("Mapper not found!");
    }
Run Code Online (Sandbox Code Playgroud)

会工作,但这不是我要找的答案.

这似乎是一般的通用抽象工厂模式的问题.还欢迎使用自定义对象提供源样本的答案.

TDJ*_*Joe 4

根据《Effective Java》,第二版,第 28 项:

如果类型参数在方法声明中仅出现一次,请将其替换为通配符。

您的 getMapperFactory 方法仅在返回类型中使用类型参数 M。遵循此建议会给出以下方法签名,并且该方法可以编译:

public static MapperFactory<? extends TaskMapper<Message, ? extends Message, ? extends String>> getMapperFactory(Message msgIn, Message msgOut)
Run Code Online (Sandbox Code Playgroud)

编辑:我看代码越多,我就越认为 MapperFactory 不应该被参数化。这里的代码中没有使用该参数,getTaskMapper返回一个TaskMapper。

  • 更短的是,签名可以只是“public static MapperFactory&lt;?&gt; getMapperFactory()”。该方法不会比“MapperFactory”的类签名更多地限制任何类型参数。“public Abstract TaskMapper&lt;?, ?, ?&gt; getTaskMapper()”也是如此。(它也可能是“公共抽象M getTaskMapper()”,无法分辨类型参数背后的意图是什么。)*“当有疑问时,少用泛型”*可能是一个很好的经验法则。 (2认同)