Java 从超类调用子类方法是';这不是最佳实践吗?

Java 从超类调用子类方法是';这不是最佳实践吗?,java,c#,oop,design-patterns,Java,C#,Oop,Design Patterns,我正在从事一个项目,其中有一个抽象类(BaseConverter),有一个抽象方法(convert())和几个具体方法。一个重要的具体方法是invokeConverter(),它基本上将调用子类中实现的convert()方法 当我们的代码被其他人审查时,他说,子类方法不应该从超类调用,他说这不是最佳实践。下面是我们的班级结构。有人能告诉我这是不是一个正确的方法吗 @Named public abstract class BaseConverter{ @Inject pri

我正在从事一个项目,其中有一个抽象类(
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
     } 
    ....
    ....
}

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

在操作中定义算法的框架,推迟一些 到子类的步骤。模板方法允许子类重新定义某些 不改变算法结构的算法步骤

您会发现这种模式在许多已知的框架和插件中实现。但是,在某些情况下,你应该考虑不同的模式,比如策略或装饰器。 例如,虽然Strategy模式使用委托来改变整个算法,但Template方法使用损坏的继承来改变算法的特定部分。该策略还在运行时修改单个对象的逻辑,而模板方法在编译时通过子类化修改整个类的逻辑


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


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

您没有调用子类方法。您只是在调用超类的重写方法。这就是为什么要把抽象方法放在首位的原因之一。“我不知道这怎么会是一个糟糕的练习。”Codebender,谢谢。。是的,我用同样的答案证明了这一点,但那家伙不相信,并要求我们改变结构。问问那家伙……让他解释一下,因为他很了解你的代码。我想问题可能在于
invokeConverter
似乎是用静态方法而不是实例方法工作的,因为它检索一些对象来进行转换。这意味着基本上必须创建一个子类实例,然后根据该类型创建另一个实例。假设当前实例是“正确的实例”,那么template方法应该直接处理当前实例,而静态方法应该选择正确的子类。@Real怀疑论者,这正是我在阅读模板模式后所做的更改。我正在移动
private ConversionDriver ConversionDriver
调用类,以便为currect实例调用
convert()
。谢谢,这是真的;但是在OP的例子中,他们实际上做了一些相当不同的事情——他们在一个单独的实例上调用模板方法。实际上根本不是“模板方法”设计模式,而且有些混乱。我必须同意审稿人的意见。agree@DavidWallace,我正在移动私人ConversionDriver ConversionDriver;调用类,以便为currect实例调用convert()。非常感谢。很好的观点@DavidWallace。我主要涉及这个问题的标题。Praki,您的重构非常好,可以正确实现此模式。@DavidArno“许多GoF模式,例如Singleton、Service Locator和Template,现在都被广泛认为是反模式。仅供参考,Service Locator不是GoF设计模式。@Maggyero,哦,您是对的。我没有发布它的起源是J2EE,而不是作为一个C++缺失的特点。谢谢你纠正了我的错误。