我有以下实现公共接口的具体类
EvaluatorA : IEvaluator
EvaluatorB : IEvaluator
EvaluatorC : IEvaluator
接口IEvaluator
只有一个函数 - Evaluate
,它在所有三种类型的求值程序中实现。我有一个驱动程序类,它根据配置调用一个求值程序,但是,它只能访问(按设计)到IEvalutor
,即,它不需要知道当前正在调用哪个具体的求值程序。
当其中一位评估员说EvaluatorC
需要实现新功能Predict
而我的要求仅针对EvaluatorC
,Predict
函数时,会出现问题需要在调用Evaluate
后调用。
时间解决方案1: 一种解决方案是检查评估者类型:
// evaluator is previously instanciated
evaluator.Evaluate();
if (evaluator is EvaluatorC)
evaluator.Predict();
正如你所看到的,这不是很整洁。明天说我需要为Dance
和EvaluatorB
仅调用另一个函数Sing
和函数EvaluatorA
,它会变得混乱。
时间解决方案2:
将函数EvaluatorB
添加到接口Predict
,对于其他评估者,只需使用空体实现该函数。这可能适用于IEvaluator
返回类型函数,但如果返回类型不是void
,则需要在驱动程序中进行额外的安全检查。另外,我不确定是否只将空体功能作为占位符是一个好主意。
时间解决方案3:
将接口更改为抽象类。这类似于解决方案2,但提供了void
的默认实现。但是,我不喜欢这种方法,因为它改变了项目的原始结构,与解决方案2相比没有带来许多好处。
总的来说,我没有一个令人满意的解决方案来解决这个问题。我希望Predict
可以提供帮助(但我不确定)。此问题并非特定于任何编程语言。请跳过并分享您的想法。
编辑1:添加了有关评估者职责的详细信息
评估者应该评估给定的解决方案并返回一些指标。获得评估指标后,驱动程序将执行一些内务处理任务,例如报告,请注意所有评估者都需要这样做。然后其中一个评估者(decoration pattern
)需要根据生成的报告调用EvaluatorC
。但是,其他评估者不需要这一步骤。
答案 0 :(得分:0)
由于我们谈论的是设计模式,我认为你所描述的内容会让人联想到template method pattern。
本质是您在基类中定义算法的骨架,并让子类选择是否要实现某些步骤。这是一个例子。
abstract class EvaluatorPredictor {
void evaluateAndPredict() {
evaluate();
predict();
}
protected void evaluate() {
// no-op
};
protected void predict() {
// no-op
};
}
class AEvaluator extends EvaluatorPredictor {
protected void evaluate() {
System.out.println("I implement this");
}
}
class BEvaluator extends EvaluatorPredictor {
protected void evaluate() {
System.out.println("I implement this");
}
protected void predict() {
System.out.println("I implement this too");
}
}
请注意,你可以通过作曲获得更多力量。例如,EvaluatorPredictor
或任何类可以使用两个分别实现Evaluator
和Predictor
接口的对象。
class Whatever {
constructor(e Evaluator, p Predictor) {
this.e = e;
this.p = p;
}
void evaluateAndPredict() {
this.e.evaluate();
this.p.predict();
}
}
PS。请原谅我糟糕的Java语法。我确定方法声明或访问修饰符中存在错误。希望上面有所帮助。