模板方法模式 (Template Method Pattern)
定义
又叫 模板模式,是指定义一个算法骨架,并允许子类为其中的一个或者多个步骤提供实现。
模板方法使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤。
属于行为型设计模式。
适用场景
- 一次性实现一个算法不变的部分,并将可变的行为留给子类实现。
- 各子类中公共的行为被提取出来,并集中到一个公共的父类中,从而避免代码重复。
对于步骤比较固定的情况,适合使用模板方法模式;而如果步骤频繁会变化的话,则不太适合模板方法模式。
标准示例
AbstractClass 为整个算法框架的顶层抽象类,其中定义了一些步骤 step1、step2、step3,是内部的实现,只能自己或子类使用;此外还有一个对外的方法 templateMethod,templateMethod 已经将step1~3 排列好执行顺序,并且不能被子类重写。
AbstractClass
public abstract class AbstractClass {protected void step1(){System.out.println("AbstractClass step1...");}protected void step2(){System.out.println("AbstractClass step2...");}protected void step3(){System.out.println("AbstractClass step3...");}//final无法被子类重写public final void templateMethod(){System.out.println("templateMethod---------begin---------");step1();step2();step3();System.out.println("templateMethod---------end---------");System.out.println();}
}
ConcreteA
、ConcreteB
分别根据自身情况,覆盖了相应的执行步骤。
public class ConcreteA extends AbstractClass{@Overrideprotected void step1() {System.out.println("ConcreteA step1...");}
}
public class ConcreteB extends AbstractClass{@Overrideprotected void step2() {System.out.println("ConcreteB step2...");}
}
ClientTest
调用类:
public class ClientTest {public static void main(String[] args) {AbstractClass abstractClassA = new ConcreteA();abstractClassA.templateMethod();AbstractClass abstractClassB = new ConcreteB();abstractClassB.templateMethod();}
}
输出结果:
templateMethod---------begin---------
ConcreteA step1...
AbstractClass step2...
AbstractClass step3...
templateMethod---------end---------templateMethod---------begin---------
AbstractClass step1...
ConcreteB step2...
AbstractClass step3...
templateMethod---------end---------
可见,AbstractClass中的方法,已经被实现类进行了调整。
这里的调整,一种是方法的覆盖;另外一种是钩子方法。
钩子方法:
由抽象类声明并且实现,子类也可以选择加以扩展。通常抽象类会给出一个空的钩子方法,也就是没有实现的扩展。它和具体方法在代码上没有区别,不过是一种意识的区别;而它和抽象方法有时候也是没有区别的,就是在子类都需要将其实现的时候。而不同的是抽象方法必须实现,而钩子方法可以不实现。也就是说钩子方法为你在实现某一个抽象类的时候提供了可选项,相当于预先提供了一个默认配置。
我们使用一个大家都熟悉的例子来演示钩子方法。
说,把大象放进冰箱,需要几步?
三步,1.打开冰箱门;2.把大象放进去;3.关上冰箱门。
那么,把长颈鹿放进冰箱,需要几步?
四部,1.打开冰箱门;2.把大象拿出来;3.把长颈鹿放进去;4.关上冰箱门。
AbstractOperate
抽象操作类:
public abstract class AbstractOperate {protected void open(){System.out.println("--------start--------");System.out.println("打开冰箱门");}protected void close(){System.out.println("关闭冰箱门");System.out.println("--------end--------");}/*** 放进去*/protected abstract void takeIn();/*** 拿出来*/ protected abstract void takeOut();/*** 检查冰箱中是否有大象* @return*/protected abstract boolean checkBridge();/*** 标准操作流程*/public void execute(){open();if(checkBridge()){takeOut();}takeIn();close();}
}
ElephantOperate
大象实现类:
public class ElephantOperate extends AbstractOperate{protected void takeIn() {System.out.println("把大象放进冰箱");}protected void takeOut() {System.out.println("把大象拿出冰箱");}protected boolean checkBridge() {return false;}
}
GiraffeOperate
长颈鹿实现类:
public class GiraffeOperate extends AbstractOperate{private boolean takeOutFlag = false;public void setTakeOut(boolean takeOutFlag) {this.takeOutFlag = takeOutFlag;}protected void takeIn() {System.out.println("把长颈鹿放进冰箱");}protected void takeOut() {System.out.println("把大象拿出冰箱");}protected boolean checkBridge() {return takeOutFlag;}
}
ClientTest
public class ClientTest {public static void main(String[] args) {ElephantOperate operate = new ElephantOperate();operate.execute();GiraffeOperate operate1 = new GiraffeOperate();operate1.setTakeOut(true);operate1.execute();}
}
执行结果:
--------start--------
打开冰箱门
把大象放进冰箱
关闭冰箱门
--------end--------
--------start--------
打开冰箱门
把大象拿出冰箱
把长颈鹿放进冰箱
关闭冰箱门
--------end--------
以上就是模板方法模式的全部内容,感谢阅读。