Java泛型抽象工厂问题

时间:2012-02-08 10:23:27

标签: 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;
    }

}

问题是编译错误:

  

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

在我的MapperFactory中:

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

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

当然替换:

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 static MapperFactory<?> getMapperFactory(Message msgIn, Message msgOut) {

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

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

会起作用,但这不是我要找的答案。

这似乎是一般的通用抽象工厂模式的问题。 使用自定义制作对象提供源样本的答案也很受欢迎。

3 个答案:

答案 0 :(得分:4)

根据Effective Java,第2版,第28项:

  

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

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

public static MapperFactory<? extends TaskMapper<Message, ? extends Message, ? extends String>> getMapperFactory(Message msgIn, Message msgOut)
编辑:我看代码越多,我认为MapperFactory就越不应该参数化。这里的代码中没有使用该参数,getTaskMapper返回一个TaskMapper。

答案 1 :(得分:1)

返回语句适用于类型转换:

return (BpmMapperFactory<MAPPER>)new Bpm007PrepareDocTaskMapperFactory();

该代码永远不会以其当前形式执行,因为Bpm007PrepareDocTaskMapper不会扩展BpmCommonMessageDto,因此msgIn不可能是Bpm007PrepareDocTaskMapper的实例。

答案 2 :(得分:1)

我的解决方案是用火焚烧尽可能多的仿制药:

abstract class MapperFactory<M extends TaskMapper<?, ?, ?>> {

    public static MapperFactory<?> getMapperFactory(Message msgIn, Message msgOut) {
        if (msgIn.isMyMapper()) return new MyTaskMapperFactory();
        throw new IllegalStateException("Mapper not found!");
    }

    public abstract M getTaskMapper();
}


class MyTaskMapperFactory extends MapperFactory<MyTaskMapper> {

    @Override
    public MyTaskMapper getTaskMapper() {
        return new MyTaskMapper();
    }

}


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);

}

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;
    }

}

如果你真的不关心它们是什么或者不需要比它们更多地限制它们,那么在每个使用它的方法中重复类的参数都没有必要。班级签名确实。