2

我知道有很多类似的问题,但如果可能的话,我没有找到一个好的和干净的解决方案。我正在用抽象类型的子类实现一个通用接口。问题是,当我调用它们时,我要么必须在 switch/case 中进行类型转换,要么在接口实现中的每个方法中进行类型转换,我无法找到一个好的和干净的方法......我最好只写下一个简短的例子。

// An abstract type with 2 implementations...
public abstract class ObjTypeAbstract {}

public class ObjType extends ObjTypeAbstract {}
public class ScriptType extends ObjTypeAbstract {}

现在两种类型的处理器都有一个接口

interface ProcessorInterface<T extends ObjTypeAbstract> {
    public void abcMethod(T obj);
}

public class ObjProcessor implements ProcessorInterface<ObjType> {
    public void abcMethod(ObjType obj) {}
}
public class ScriptProcessor implements ProcessorInterface<ScriptType> {
    public void abcMethod(ScriptType obj) {}
}

我正在苦苦挣扎的是一种基于 ObjAbstractType 调用这些处理器的方法。我有一个作为中间件服务器的类?或者我应该怎么称呼它。:

想法是通过单个开关/机箱简单地获得正确的处理器:

public class Processor {
    private ProcessorInterface objProcessor = new ObjProcessor();
    private ProcessorInterface scriptProcessor = new ScriptProcessor();

    public methodAbc(ObjAbstractType obj) {
        getProcessor(obj).abcMethod(obj);
    }

    private ProcessorInterface getProcessor(ObjAbstractType obj) {
        if (obj instanceof ObjType) {
            return objectProcessor;
        } else if (obj instanceof ScriptType) {
            return scriptProcessor;
        }

        return nullProcessor;
    }
}

这就是我想要的,它还负责将 objAbstract 类型转换为 abcMethod 的实际类型,问题是它会导致 RawType 警告不会破坏代码,但我想摆脱它。

这就是我卡住的地方......因为如果我将处理器转换为这样的特定类型:

private ProcessorInterface<ObjType> objProcessor = new ObjProcessor();
private ProcessorInterface<ScriptType> scriptProcessor = new ScriptProcessor();

我将无法从 getProcessor 方法返回抽象接口,因此我必须使用 ObjAbstractType 及其所有方法实现这些接口,并在每个处理器的所有方法中进行类型转换,例如:

public class ScriptProcessor implements ProcessorInterface<ObjAbstractType> {
    public void abcMethod(ObjAbstractType obj) {
        ScriptType scr = (ScriptType) obj;
    }
}

另一个解决方案可能是在处理器中间件类中有一个开关/案例并在其中转换 ObjAbstractType,但我必须在 abcMethod 和所有其他方法中编写该开关,或者从 getProcessor 方法返回处理器和转换的 ObjType ......所以我必须返回一些包含两者的 dto。:/

您是否有任何想法/模式可以帮助我摆脱 RawType 调用警告,而无需使用更多开关/案例或类型转换扩展代码?祝你有美好的一天,我会很高兴任何讨论,大卫。

4

2 回答 2

1

您需要一种方法来存储ObjTypeAbstract类和ProcessorInterface实例之间的映射。
您可以使用将s(作为键)与 s(作为值)Map相关联的 a。 关于原始类型问题,您可以使用 声明的变量,但您仍然需要执行不安全的强制转换才能将声明的类型作为参数调用。 这种演员阵容在你的实际设计中是不可避免的。 ObjTypeAbstractProcessorInterface
ProcessorInterface<? extends ObjTypeAbstract>ProcessorInterface<ObjTypeAbstract>ProcessorInterface.abcMethod()ObjTypeAbstract

它可以给出类似的东西:

public class Processor {

    private Map<Class<? extends ObjTypeAbstract>, ProcessorInterface<? extends ObjTypeAbstract >> map = new HashMap<>();

    public Processor(){
        map.put(ObjType.class, new ObjProcessor());
        map.put(ScriptType.class, new ScriptProcessor());   
    }
    public void methodAbc(ObjTypeAbstract obj) {
        @SuppressWarnings("unchecked")
        ProcessorInterface<ObjTypeAbstract> processorInterface = (ProcessorInterface<ObjTypeAbstract>) map.get(obj.getClass());
        processorInterface.abcMethod(obj);
    }

}
于 2018-09-09T10:27:30.633 回答
0

我认为没有一种更优雅的方式来绕过某种形式的instanceof逻辑。但是,如果您将某些类型添加到getProcessor.

    public <T extends ObjTypeAbstract> ProcessorInterface<T> getProcessor(Class<T> theClass) {
        if (theClass.isAssignableFrom(ObjType.class)) {
            return objProcessor;
        } else if (theClass.isAssignableFrom(ScriptType.class)) {
            return scriptProcessor;
        }
        return null;
    }

然后可以这样调用:

    ProcessorInterface<ScriptType> scriptProcessor = new Processor().getProcessor(ScriptType.class);
    ProcessorInterface<ObjType> objProcessor = new Processor().getProcessor(ObjType.class);
于 2018-09-09T10:47:26.427 回答