[英]Invoke concrete class functions through common interface
I have the following concrete classes that implement a common interface 我有以下实现通用接口的具体类
EvaluatorA : IEvaluator
EvaluatorB : IEvaluator
EvaluatorC : IEvaluator
The interface IEvaluator
has only one function - Evaluate
, which is implemented in all three types of evaluators. 接口IEvaluator
只有一个功能- Evaluate
,这是在所有三种评估的实施。 And I have a driver class that invokes an evaluator based on configuration, however, it is only having access (by design) to IEvalutor
, ie, it does not need to know which concrete evaluator is currently being invoked. 我有一个驱动程序类,该类基于配置调用评估器,但是,它只能(通过设计)对IEvalutor
,即,它不需要知道当前正在调用哪个具体评估器。
The problem arises when one of the evaluators, say EvaluatorC
, needs to implement a new function Predict
, and my requirement is only for EvaluatorC
, the Predict
function needs to be called after calling Evaluate
. 当其中一个评估程序(例如EvaluatorC
)需要实现新功能Predict
,就会出现问题,而我的要求仅是对EvaluatorC
,需要在调用Evaluate
之后调用Predict
函数。
Temporal solution 1: One solution is to check the evaluator type: 临时解决方案1:一种解决方案是检查评估者类型:
// evaluator is previously instanciated
evaluator.Evaluate();
if (evaluator is EvaluatorC)
evaluator.Predict();
As you could see, this is not neat. 如您所见,这并不整齐。 Say tomorrow I need to call another function Dance
for only EvaluatorB
and function Sing
for both EvaluatorA
and EvaluatorB
, it becomes messy. 明天再说我需要调用另一个函数Dance
只EvaluatorB
和功能Sing
两个EvaluatorA
和EvaluatorB
,它变得凌乱。
Temporal solution 2: Add function Predict
to the interface IEvaluator
, and for other evaluators, just implement the function with an empty body. 临时解决方案2:将函数Predict
添加到接口IEvaluator
,对于其他评估器,只需将函数实现为空即可。 This could work for void
return type functions, but it needs additional safety check in the driver program if the return type is not void
. 这可能适用于void
返回类型函数,但是如果返回类型不是void
,则需要在驱动程序中进行其他安全检查。 In addition, I am not sure if having a function with empty body only as placeholders is a good idea or not. 另外,我不确定仅将空函数用作占位符是否是一个好主意。
Temporal solution 3: Change the interface to an abstract class. 临时解决方案3:将接口更改为抽象类。 This is similar to solution 2, but provides a default implementation of Predict
. 这类似于解决方案2,但是提供了Predict
的默认实现。 However, I did not like this approach either as it alters the original structure of the project and does not bring many benefits compared to solution 2. 但是,我也不喜欢这种方法,因为它改变了项目的原始结构,与解决方案2相比并没有带来很多好处。
Overall, I do not have a satisfying solution to this problem. 总的来说,我对这个问题没有令人满意的解决方案。 I am hoping that decoration pattern
could help (but I am not sure). 我希望decoration pattern
可以有所帮助(但我不确定)。 This problem is not specific to any programming languages. 此问题并非特定于任何编程语言。 Please jump in and share your ideas. 请加入并分享您的想法。
Edit 1: Added some details about Evaluator responsibilities Evalutors are supposed to evaluate a given solution and return some metrics. 编辑1:添加了有关评估者职责的一些详细信息评估者应评估给定的解决方案并返回一些度量。 After getting the evaluation metrics, driver program will do some housekeeping task, such as reporting, note that this is needed for all evaluators. 获取评估指标后,驱动程序将执行一些内部管理任务,例如报告,请注意,所有评估者都需要这样做。 And then one of the evaluators ( EvaluatorC
) needs to call Predict()
based on the generated reports. 然后,其中一个评估者( EvaluatorC
)需要根据生成的报告来调用Predict()
。 However, the other evaluators do not require this step. 但是,其他评估者不需要此步骤。
Since we're talking about design patterns, I think what you're describing brings to mind the template method pattern . 由于我们正在谈论设计模式,因此我认为您所描述的内容使我想到了模板方法pattern 。
The essence is that you define the skeleton of your algorithm in an base class and let subclasses choose whether they want to implement certain steps or not. 本质是,您可以在基类中定义算法的框架,然后让子类选择是否要实现某些步骤。 Here's an example. 这是一个例子。
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");
}
}
Please note that you can get more power with composition. 请注意,您可以通过合成获得更多功能。 For example the EvaluatorPredictor
, or any class for that matter, could use two objects that implement an Evaluator
and Predictor
interface respectively. 例如, 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. PS。 Excuse my poor Java-like syntax. 请原谅我糟糕的类似于Java的语法。 I'm sure there are errors in method declarations or access modifiers. 我确定方法声明或访问修饰符中有错误。 Hope the above helps though. 希望以上帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.