模板模式,但其中一个类未实现该方法

时间:2019-02-06 13:05:16

标签: java oop design-patterns

我正在尝试实现Template方法模式,但是我需要一些我认为不是最佳实践的变化。 我的班级结构如下

abstract class AbsClass {
    public void algorithm(){
        step1();
        step2();
    }
    private void step1() {
        //implementation
    }

    protected abstract void step2();
}

class A extends AbsClass {
    protected void step2() {
        // With implementation
    }
}

class B extends AbsClass {
    protected void step2() {
        // No implementation needed
    }
}

在实际情况下,我喜欢4个类,其中一个不需要第二步实现。我不认为将方法保留为空是一种好习惯。我当时正在考虑在其中发表评论(说不需要实施),但是我认为这不是正确的解决方案。 还有我看不到的另一种方法吗?

3 个答案:

答案 0 :(得分:2)

我认为这绝对可以。如果step2的默认行为是什么都不做,那么您可以在基类中使用一个空方法,并在子类中进行覆盖。

答案 1 :(得分:2)

我同意@Vinay Avasthi的回答,但我想加强它。

挂钩方法

Hook方法在基类中定义,并且是默认实现。而这些 可以被覆盖-不必。

Template-Method-Pattern Wikipedia页上:

  

Template方法的抽象类还可以定义可以被子类覆盖的hook方法。这些在抽象类中具有no-op实现,但是提供了一个“挂钩”,可以在其上“挂起”实现。

改进

您应该做的是在诸如// empty method body之类的方法主体中添加注释,以使阅读您的代码(也许您自己)的人知道该方法没有被忘记

Java的默认方法

还有第二种方法来用Java实现模板方法。从Java 8开始,可以在接口中具有默认的方法实现。

如果您的方法不依赖状态,则可能看起来像这样:

interface AbsClass {

  default void algorithm(){
    step1();
    step2();
  }

  default void step1() {
    // implementation or empty
  }

  default void step2() {
    // empty body in default case
  }
}

class B implements AbsClass { }

答案 2 :(得分:2)

我们不应该强制设计模式。在这里,如果我们更喜欢组合而不是继承,那么更好。

问题中存在的代码我们在类中定义了一个方法,但实际上该方法没有任何行为。在一个不应将其束缚的类中强制使用方法不是一个好主意。

下面是一个这样的可能实现,其中如果某个方法不属于某个类,则您不会将其强制给该类。下面是基于策略模式的,但是我仍然要遵循设计原则,并让模式本身适合您的问题,而不是强迫模式适合您的解决方案。

public class AlgorithmClass {
    private Strategy strategy;
    public void setStrategy(Strategy strategy){
        this.strategy = strategy;
    }
    public void algorithm(){
        step1();
        step2();
    }
    private void step1() {
        //implementation
    }

    private  void step2(){
        if(this.strategy != null){
              this.strategy.execute();
       }
    }
}

public interface Strategy{
    public void execute();
}

public class Strategy1 implements Strategy{
    public void execute(){
         //implement your one of the stategies for step 2
   }
}

public class Strategy2 implements Strategy{
    public void execute(){
         //implement your another stategy for step 2
   }
}