Java 模板方法:当您希望能够灵活地更改原语选项时,如何使用它?

Java 模板方法:当您希望能够灵活地更改原语选项时,如何使用它?,java,design-patterns,code-duplication,strategy-pattern,template-method-pattern,Java,Design Patterns,Code Duplication,Strategy Pattern,Template Method Pattern,下面的代码可以很好地解释此问题: public class TemplateClass { public void templateOne() { checkConditionA(); primitiveOp1(); checkConditionB(); } public void templateTwo() { checkConditionA(); primitiveOp2();

下面的代码可以很好地解释此问题:

public class TemplateClass {
    public void templateOne() {
        checkConditionA();
        primitiveOp1();
        checkConditionB();
    }

    public void templateTwo() {
        checkConditionA();
        primitiveOp2();
        checkConditionB();
    }

    protected abstract void primitiveOp1();
    protected abstract void primitiveOp2();
    // rest of the methods
}

  

现在我有了templateOne()和templateTwo()的代码复制,但我希望只有一个模板方法,但可以使用可互换的基本操作。

实际上,您需要的是围绕方法调用的保护块。这是一个很好的做法,但被劝告的是,你们不应该把不应该耦合的东西结合起来。我只会将这两种方法结合起来,前提是它们必须始终由相同的前置和后置条件保护

如果是这种情况,我建议实现一个方法
private void callWithChecks(Runnable primitiveOperation)
,然后将相应的原语操作作为参数传递给此方法:

public abstract class TemplateClass {
    public void templateOne() {
        callWithChecks(this::primitiveOp1);
    }

    public void templateTwo() {
        callWithChecks(this::primitiveOp2);
    }

    private void callWithCkecks(Runnable primitiveOperation) {
        checkConditionA();
        primitiveOperation.run();
        checkConditionB();
    }

    protected abstract void primitiveOp1();
    protected abstract void primitiveOp2();
    // rest of the methods
}
如果不想使用函数接口
Runnable
,当然可以定义自己的接口。我选择了它,因为它是一个Java基类


关于您的代码,请注意两点:

  • TempalteClass
    必须声明为
    abstract
    ,否则代码将无法编译
  • 如果您打算在
    TemplateClass
    中实现方法
    checkConditionA()
    checkConditionB()
    ,我建议将它们定义为
    private
    final
    ,这样它们就不能被重写

您可以将
基本操作
作为参数传递给方法。