【发布时间】:2018-03-14 17:56:26
【问题描述】:
我有以下实现通用接口的具体类
EvaluatorA : IEvaluator
EvaluatorB : IEvaluator
EvaluatorC : IEvaluator
接口IEvaluator只有一个功能——Evaluate,它在所有三种类型的求值器中都实现了。而且我有一个驱动程序类,它根据配置调用评估器,但是,它只能(通过设计)访问IEvalutor,即,它不需要知道当前正在调用哪个具体的评估器。
当其中一位评估者,比如说EvaluatorC,需要实现一个新函数Predict,而我的要求只针对EvaluatorC,Predict函数需要在调用@987654329之后调用@。
临时解决方案 1: 一种解决方案是检查评估器类型:
// evaluator is previously instanciated
evaluator.Evaluate();
if (evaluator is EvaluatorC)
evaluator.Predict();
如您所见,这并不整洁。假设明天我需要为 EvaluatorB 调用另一个函数 Dance 并为 EvaluatorA 和 EvaluatorB 调用函数 Sing,它变得混乱。
时间解2:
将函数Predict添加到接口IEvaluator中,对于其他的求值者,只需用空体实现函数即可。这可能适用于void 返回类型的函数,但如果返回类型不是void,则需要在驱动程序中进行额外的安全检查。此外,我不确定将空体仅作为占位符的函数是否是一个好主意。
临时解决方案 3:
将接口更改为抽象类。这类似于解决方案 2,但提供了Predict 的默认实现。但是,我也不喜欢这种方法,因为它改变了项目的原始结构,并且与解决方案 2 相比并没有带来太多好处。
总的来说,我对这个问题没有满意的解决方案。我希望decoration pattern 可以提供帮助(但我不确定)。此问题并非特定于任何编程语言。请加入并分享您的想法。
编辑 1:添加了有关评估员职责的一些详细信息
评估者应该评估给定的解决方案并返回一些指标。得到评估指标后,驱动程序会做一些家务,比如报告,注意这是所有评估者都需要的。然后其中一位评估者 (EvaluatorC) 需要根据生成的报告调用 Predict()。但是,其他评估者不需要此步骤。
【问题讨论】:
-
为什么不在
EvaluatorC的Evaluate方法中调用Predict? -
@sdgfsdh,好点子。最初的计划是这样,但是在调用
Evaluate()之后发现驱动程序中需要做一些内务工作。之后才能调用Predict()。 -
那么驱动程序是否也在
Evaluate方法中工作?您似乎还没有为您的问题找到合适的抽象。 -
在不知道
Evaluate和Predict实际在做什么的情况下很难提供帮助。听起来Predict对于Evaluator来说并不常见,所以它不应该在那个类中。您可以将它移动到另一个类Predictor,在调用evaluate之后,您将在driver类中使用该类。 Predictor 可以接收来自Evaluator的响应并执行其操作。
标签: design-patterns interface abstract-class decorator object-oriented-analysis