通过通用接口

时间:2017-10-03 13:49:53

标签: design-patterns interface abstract-class decorator object-oriented-analysis

我有以下实现公共接口的具体类

EvaluatorA : IEvaluator
EvaluatorB : IEvaluator
EvaluatorC : IEvaluator

接口IEvaluator只有一个函数 - Evaluate,它在所有三种类型的求值程序中实现。我有一个驱动程序类,它根据配置调用一个求值程序,但是,它只能访问(按设计)到IEvalutor,即,它不需要知道当前正在调用哪个具体的求值程序。

当其中一位评估员说EvaluatorC需要实现新功能Predict而我的要求仅针对EvaluatorCPredict函数时,会出现问题需要在调用Evaluate后调用。

时间解决方案1: 一种解决方案是检查评估者类型:

// evaluator is previously instanciated
evaluator.Evaluate();
if (evaluator is EvaluatorC)
    evaluator.Predict();

正如你所看到的,这不是很整洁。明天说我需要为DanceEvaluatorB仅调用另一个函数Sing和函数EvaluatorA,它会变得混乱。

时间解决方案2: 将函数EvaluatorB添加到接口Predict,对于其他评估者,只需使用空体实现该函数。这可能适用于IEvaluator返回类型函数,但如果返回类型不是void,则需要在驱动程序中进行额外的安全检查。另外,我不确定是否只将空体功能作为占位符是一个好主意。

时间解决方案3: 将接口更改为抽象类。这类似于解决方案2,但提供了void的默认实现。但是,我不喜欢这种方法,因为它改变了项目的原始结构,与解决方案2相比没有带来许多好处。

总的来说,我没有一个令人满意的解决方案来解决这个问题。我希望Predict可以提供帮助(但我不确定)。此问题并非特定于任何编程语言。请跳过并分享您的想法。

编辑1:添加了有关评估者职责的详细信息 评估者应该评估给定的解决方案并返回一些指标。获得评估指标后,驱动程序将执行一些内务处理任务,例如报告,请注意所有评估者都需要这样做。然后其中一个评估者(decoration pattern)需要根据生成的报告调用EvaluatorC。但是,其他评估者不需要这一步骤。

1 个答案:

答案 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或任何类可以使用两个分别实现EvaluatorPredictor接口的对象。

class Whatever {
  constructor(e Evaluator, p Predictor) {
    this.e = e;
    this.p = p;
  }

  void evaluateAndPredict() {
    this.e.evaluate();
    this.p.predict();
  }
}

PS。请原谅我糟糕的Java语法。我确定方法声明或访问修饰符中存在错误。希望上面有所帮助。