简体   繁体   English

通过通用接口调用具体的类函数

[英]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. 明天再说我需要调用另一个函数DanceEvaluatorB和功能Sing两个EvaluatorAEvaluatorB ,它变得凌乱。

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

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.

相关问题 代码气味-仅1个具体的类和接口 - Code smell - only 1 concrete class and interface 如何将接口注入具体的类层次结构 - How to inject an interface into a concrete class hierarchy 如何通过单个公共接口(类)抽象化对不同类型对象的访问? - How can I abstract away access to different types of objects through a single common interface (class)? 具体类应该遵循其接口的类型提示吗? - Should concrete class follow the type hint of its interface? 用C#库类组成一个通用接口 - Composing a common interface with c# library class 这种设计模式是否有名称,其中具体类实现了一个特定接口,该接口实现了 CRUD 操作的基本接口? - Is there a name for this design pattern where a concrete class implements a specific interface which implements a base interface for CRUD operations? 如何在组件之间共享具有非通用功能的通用类? - How to share common class with non-common functions among components? 通过通用接口包装C#类以与多态性一起使用 - Wrapping C# classes to use with polymorphism through a common interface 在需要时从接口转换为一些具体的类是一个好习惯? - Its is a good practice to cast from an interface to some concrete class when needed? 如果在代理模式中我们有接口而不是实际的具体主题在Proxy类中它等同于Decorator模式 - If In Proxy Pattern we have interface instead of actual concrete Subject in Proxy class is it equivalent to Decorator Pattern
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM