问题描述
最好用以下代码解释该问题:
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()复制了代码,但是我只想使用一种模板方法,但是可以互换原始操作。
解决方法
本质上,您想要的是方法调用周围的保护块。 DRY programming是一种很好的做法,但请注意,不要随意耦合不应耦合的对象。如果可以确保必须始终用相同的前置条件和后置条件来保护这两种方法,那么我只会结合使用这两种方法。
在这种情况下,我建议实现方法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
,否则代码将无法编译 - 如果您打算在
checkConditionA()
中实现方法checkConditionB()
和TemplateClass
,则建议将它们定义为private
或final
,以使它们不会被覆盖