如何使用参数

时间:2017-01-21 07:16:13

标签: java generics

所以我有以下结构:

public abstract class Processor<T extends BaseContainer> {
    protected abstract T initializeContainer(String requestID, Map<String, String> details);

    protected abstract boolean validateContainer(T request);
    protected abstract void process(T request);

    public final process(String requestID, Map<String, String> details) {
        T request = initializeContainer(requestID, details);
        if (!validateContainer(request)) {
            process(request);
        }
    }
}

public abstract class BaseContainer() {
    protected final String requestID;
    protected BaseContainer(String requestID, Map<String, String> details) {
        this.requestID = requestID;
        // set some other fields using details
    }
}

每次我需要添加一个新的Processor(带有相应的新Container)时,我需要:

public class SampleProcessor extends Processor<SampleContainer> {
    @Override
    protected SampleContainer initializeContainer(String requestID, Map<String, String> details) {
        return new SampleContainer(requestID, details);
    }
}

// SampleContainer can contain other details, but omitted for clarity
public class SampleContainer extends BaseContainer {
    public SampleContainer(String requestID, Map<String, String> details) {
        super(requestID, details);
    }
}

我不喜欢我需要为我添加的每个处理器覆盖initializeContainer的事实,特别是当我不更改构造函数的Container参数时(它总是String requestID, Map<String, String> details

我知道我无法在new T(requestID, details)中简单地致电Processor。如果我想在基类实现initializeContainer,我想我会需要某种工厂(?)。

无论如何我能帮你建议我能做到吗?谢谢。

编辑1:我添加了两个方法来提供更好的上下文处理器

2 个答案:

答案 0 :(得分:1)

一切都很好

这是一种名为enter image description here的模式。

  

每次我需要添加一个新的Processor(带有相应的新Container)时,我需要:

这是模式的主要目的(ebenda)

  

客户端(您)软件创建抽象工厂(Processor)的具体实现(您的SampleProcessor),然后使用工厂的通用接口创建(通过initializeContainer)具体对象(您的SampleContainer)... < / p>

答案 1 :(得分:0)

我将方法名称重构为createContainer,因为这与您的实施有关 - 您不会设置现有名称,而是创建一个新名称。< / p>

您的简单示例仅调用容器构造函数。但是处理器的创建和初始化&#39;过程可能有所不同也许,某些容器的某些处理器需要特殊处理。然后,该方法的实现将再次针对每个容器子类看起来不同。

解决这个常见问题的另一种常见模式是添加另一种抽象方法,如

public abstract Class<T> getProcessorType();

并在每个容器实现上实现它:

@Override
public Class<MyProcessor> getProcessorType() {
    return MyProcessor.class;
}

然后基类可以为处理器实现create方法:

public T createProcessor(String requestID, Map<String, String> details) {
    T processor;
    try {
        processor = getProcessorType().newInstance();
    } catch (InstantiationException | IllegalAccessException e) {
        e.printStackTrace();  // or handle correctly
    }
    processor.init(requestId, details)
    return processor;
}

(注意,这需要一个no-args处理器构造函数)