【问题标题】:Calling the sub class method from super class isn't best practice?从超类调用子类方法不是最佳实践吗?
【发布时间】:2015-07-23 09:34:17
【问题描述】:

我正在做一个项目,我们有一个抽象类 (BaseConverter),它有一个抽象方法 (convert()) 和几个具体方法。一个重要的具体方法是invokeConverter(),它基本上会调用子类中实现的convert() 方法。

当其他人正在审查我们的代码时,他告诉说,不应该从超类调用子类方法,他告诉这不是最佳实践。下面是我们的类结构。有人可以告诉这是否不是正确的方法吗?

@Named
public abstract class BaseConverter{ 

     @Inject
     private ConversionDriver conversionDriver;//this class is responsible to return the correct subclass object based on the type

     protected abstract String convert(Object toConvert); 

     public String invokeConverter(ConverterType type, Object toConvert){
       conversionDriver.getConverter(type).convert(toConvert);//getConverter() return the subclass object based on the type
     } 
    ....
    ....
}

【问题讨论】:

  • 你没有调用子类方法。您只是在调用超类的重写方法。这就是首先使用抽象方法的原因之一。我不知道这会是什么不好的做法。
  • @Codebender,谢谢.. 是的,我用相同的答案证明了这一点,但那个人不相信并要求我们改变结构。
  • 问那个人......让他解释一下,因为他很了解你的代码。
  • 我认为问题可能在于invokeConverter 似乎完成了静态方法而不是实例方法的工作,因为它检索了一些对象来进行转换。这意味着基本上必须创建一个子类实例,然后根据该类型创建另一个实例。模板方法应该直接与当前实例一起工作,假设它是“正确的实例”,并且静态方法应该选择正确的子类。
  • @RealSkeptic,这是我在阅读模板模式后所做的确切更改。我正在将private ConversionDriver conversionDriver; 移动到调用类,以便为当前实例调用convert()。非常感谢。

标签: java c# oop design-patterns


【解决方案1】:

它实际上是一种被GoF称为模板方法的设计模式。但是,您不应该过度应用它,因为它有利于继承而不是组合。

在一个操作中定义一个算法的骨架,推迟一些 子类的步骤。模板方法让子类重新定义某些 算法的步骤而不改变算法的结构。

您会发现这种模式已在许多已知的框架和插件中实现。但是,在某些情况下,您应该考虑不同的模式,例如策略或装饰器。

例如,虽然策略模式使用委托来改变整个算法,但模板方法使用被诽谤的继承来改变算法的特定部分。策略也在运行时修改单个对象的逻辑,而模板方法在编译时通过子类化修改整个类的逻辑。


关于“最佳实践” - 这是一个有争议的术语。我认为,当代码库增长并且需要重构以获得更好的复杂性时,应该替换模板方法以支持更好的设计模式。

但有时它是满足您需求的最佳解决方案。例如,您可能有doExecute() 方法,并希望其他程序员扩展您的类(但不修改它),因此您让他们挂钩到提供beforeExecute() 方法的代码部分。如果我们谈到各种对象的组合,成熟的系统可能会包含事件调度器功能。

【讨论】:

  • 这是真的;但在 OP 的示例中,他们实际上在做一些完全不同的事情——他们在单独的实例上调用模板方法。根本不是真正的“模板方法”设计模式,而且有些混乱。我必须同意评论者的意见。
  • 同意@DavidWallace,我正在移动私有 ConversionDriver 转换驱动器;到调用类,以便为当前实例调用 convert()。非常感谢。
  • 好点@DavidWallace。我主要与这个问题的标题有关。 Praki,您的重构很棒,可以正确实现此模式。
  • @DavidArno '许多 GoF 模式,例如 Singleton、Service Locator 和 Template,现在都被广泛认为是反模式。'仅供参考,Service Locator 不是 GoF 设计模式。
  • @Maggyero,哦,你是对的。我还没有发布它的起源是 J2EE,而不是作为 C++ 缺少的功能解决方法。谢谢你把我说对了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-24
相关资源
最近更新 更多