gpt4 book ai didi

java - 需要帮助使这些类使用访问者模式和泛型

转载 作者:太空宇宙 更新时间:2023-11-04 08:53:04 25 4
gpt4 key购买 nike

我需要帮助来生成和实现访问者模式。我们正在使用大量的instanceof这是一种痛苦。我确信它可以修改,但我不知道如何修改。

基本上我们有一个接口(interface)ProcessData

public interface ProcessData {
public setDelegate(Object delegate);
public Object getDelegate();
//I am sure these delegate methods can use generics somehow
}

现在我们有一个类ProcessDataGeneric实现 ProcessData

public class ProcessDataGeneric implements ProcessData {
private Object delegate;

public ProcessDataGeneric(Object delegate) {
this.delegate = delegate;
}
}

现在有一个检索 ProcessData 的新接口(interface)

interface ProcessDataWrapper {
public ProcessData unwrap();
}

现在是一个实现包装器的通用抽象类,以便可以检索 ProcessData

@XmlSeeAlso( { ProcessDataMotorferdsel.class,ProcessDataTilskudd.class })
public abstract class ProcessDataCommon implements ProcessDataWrapper {
protected ProcessData unwrapped;

public ProcessData unwrap() {
return unwrapped;
}
}

现在实现

public class ProcessDataMotorferdsel extends ProcessDataCommon {

public ProcessDataMotorferdsel() {
unwrapped = new ProcessDataGeneric(this);
}
}

同样

public class ProcessDataTilskudd extends ProcessDataCommon {

public ProcessDataTilskudd() {
unwrapped = new ProcessDataGeneric(this);
}
}

现在当我使用这些类时,我总是需要做instanceof

ProcessDataCommon pdc = null;
if(processData.getDelegate() instanceof ProcessDataMotorferdsel) {
pdc = (ProcessDataMotorferdsel) processData.getDelegate();
} else if(processData.getDelegate() instanceof ProcessDataTilskudd) {
pdc = (ProcessDataTilskudd) processData.getDelegate();
}

我知道有更好的方法来做到这一点,但我不知道如何利用泛型和访问者模式。非常感谢任何帮助。

更新

我想补充一点,这些类只是一个更大的实现的片段。ProcessDataProcessDataGeneric是代表之外的东西(ProcessDataMotorferdsel等等)。代表们纷纷伸出ProcessDataCommon .

我同意重构可能是最好的选择,但这是 2 年前的生产代码,重构成本很高(时间、测试等)。不过,我愿意这么做。

更新#2

我尝试启动通用进程,但是遇到编译错误。这就是现在的样子。

public interface ProcessData<T extends ProcessDataCommon> {
T getDelegate();
setDelegate(T delegate);
}

public class ProcessDataGeneric<T extends ProcessDataCommon> implements ProcessData<T> {
private T delegate;
//Getter & setter
public ProcessDataGeneric(T delegate) {
this.delegate = delegate;
}
}

public class ProcessDataMotorferdsel extends ProcessDataCommon {
public ProcessDataMotorferdsel() {
unwrapped = new ProcessDataGeneric<ProcessDataMotorferdsel>(this);
}
}

我在线得到编译错误:unwrapped = new ProcessDataGeneric<ProcessDataMotorferdsel>(this);

[javac] ProcessDataMotorferdsel.java:52: incompatible types
[javac] found : ProcessDataGeneric<ProcessDataMotorferdsel>
[javac] required: ProcessData<ProcessDataCommon>
[javac]

我无法弄清楚该错误消息。 ProcessDataMotorferdsel 类扩展了 ProcessDataCommon,因此在我看来它应该可以工作。

最佳答案

这个答案可能过于简单化,但我认为理想的解决方案几乎可以消除您问题中的所有代码。对于试图回答这个问题的人来说,问题在于代码试图解决的真正问题并不清楚剩下的是什么。

重构 instanceof 的常见方法是将子类与“告诉而不是询问”风格的界面结合使用。如果您可以告诉 ProcessDataGeneric 为您完成整个任务,则无需向 ProcessDataGeneric 询问其委托(delegate),如下所示:

public interface ProcessData {
public <T> T process(Data data);
}

public class ProcessDataGeneric implements ProcessData {
private ProcessData delegate;

public ProcessDataGeneric(ProcessData delegate) {
this.delegate = delegate;
}

public <T> T process(Data data) {
return delegate.process(data);
}

我什至不确定您是否真的需要 ProcessDataGeneric,因为它所做的只是保存真正的 ProcessData 子类:

public class ProcessDataMotorferdsel implements ProcessData {

// Process the data the Motorferdsel way.
public <T> T process(Data data) { ... }
}

public class ProcessDataTilskudd implements ProcessData {

// Process the data the Tilskudd way.
public <T> T process(Data data) { ... }
}

...然后你可以像这样使用子类:

ProcessData processor = new ProcessDataMotorferdsel();
Result result = processor.process(data);

...无需担心代表及其类型。

通常最好使用工厂类而不是构造函数来获取子类实例,特别是在需要计算正确的子类时。

关于java - 需要帮助使这些类使用访问者模式和泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2927540/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com