如何避免在策略模式中使用java和泛型进行未经检查的强制转换

时间:2014-06-14 18:09:18

标签: java generics design-patterns strategy-pattern

我在java中有一个编码模式,这是策略模式的一些风格。我的问题是代码需要一个未经检查的强制转换,我想避免。为了简要解释一下,我首先要有一组共享一个共同界面的类:

interface IType {}

class TypeA implements IType {}
class TypeB implements IType {}

然后我有一套策略可以对IType对象进行一些特定的处理。

interface IStrategy<T extends IType> {
    specificProcessing(T o);
}

最后,我有一个单例,它对ITypes进行一些通用处理,然后获取适当的IStrategy来进行特定的处理。 IStrategy对象在map中注册,我认为方法签名确保只有匹配的IType和IStrategies对进入地图。

class Context {

    private Map<Class<? extends IType>, IStrategy<? extends IType>> map;

    public static Context getInstance() {}

    public <T extends IType> void register(IStrategy<T> s, Class<T> c) {
        map.put(c, s);
    }

    public <T extends IType> void genericProcessing(T o) {
        //do generic stuff with o
        @SuppressWarnings("unchecked") 
        IStrategy<T> s = (IStrategy<T>) map.get(o.getClass());
        s.specificProcessing(o);
    }

}

&#34;问题&#34;是未经检查的投射警告。我知道这是因为地图的声明允许不匹配的IType和IStrategy对。我也知道代码是类型安全的,因为register()。但有没有其他设计可以避免未经检查的演员?

我很感激任何意见,谢谢。

1 个答案:

答案 0 :(得分:1)

使用此地图时无法避免它。我建议将地图访问移动到一个单独的方法中,这样代码就会更清晰地读取。

@SuppressWarnings("unchecked")
private <T extends IType> IStrategy<T> getStrategy(T o) {
    return (IStrategy<T>) map.get(o.getClass());
}
顺便说一下,你可以用scala来做。

编辑:

您可以在Octarine中执行此操作,请参阅blog on post Extractors。但也许这只是一种奇特的方式,或者将逻辑转移到它自己的方法上,但却带来了很多复杂性。