定义一个抽象类。
核心是一个不可变的模板方法,由它来定义算法结构。
子类则可以改写算法中的一些具体步骤。
像这样:
public final void templateMethod() { step1(); step2(); step3(); }
protected abstract void step3(); protected abstract void step2(); protected abstract void step1();
为了防止算法被子类随意改写,加上final关键字。
但是模板方法也不是绝对定死的,也可以加入一个钩子(Hook)方法来改变模板方法的运行过程。
像这样:
protected boolean isBlahBlah() { return true; }
于是模板方法就可以写成这样:
public final void templateMethod() { step1(); step2(); if (isBlahBlah()) { step3(); } }
子类可以自行改写钩子方法来决定要不要执行第三步的方法。
对的,模板方法的自由度非常低,但是有的时候秩序和自由一样重要。
于是先总结一下,写出一个抽象类来。
1 abstract class AbstractClass { 2 public final void templateMethod() { 3 step1(); 4 step2(); 5 6 if (isBlahBlah()) { 7 step3(); 8 } 9 } 10 11 protected boolean isBlahBlah() { 12 return true; 13 } 14 15 protected abstract void step3(); 16 protected abstract void step2(); 17 protected abstract void step1(); 18 }
之后就可以开始继承扩展了,比如我们写一个子类:
1 public class ConcreateClass1 extends AbstractClass { 2 @Override 3 protected void step3() { 4 // 不拉不拉 5 } 6 7 @Override 8 protected void step2() { 9 // 不辣不辣 10 } 11 12 @Override 13 protected void step1() { 14 // 布腊步邋 15 } 16 }
子类1直接继承了抽象类实现过的钩子方法,所以执行起来就是依次执行一二三步的方法。
子类1改写了三步方法的实现内容,但是模板方法规定好了的步骤是不会变的。
然后演示钩子方法的作用,我们写一个子类2:
1 public class ConcreateClass2 extends AbstractClass { 2 3 @Override 4 protected void step3() { 5 // 部喇埠旯 6 } 7 8 @Override 9 protected void step2() { 10 // 輹蝋鳪嚹 11 } 12 13 @Override 14 protected void step1() { 15 // булабула 16 } 17 18 @Override 19 protected boolean isBlahBlah() { 20 return false; 21 } 22 }
子类2重写了钩子方法,让它返回false,于是在执行子类的模板方法的时候第三步就不会被执行了。
虽然写了长长的一大篇,但是其实是很好理解的一种设计模式,简单到我今天一天就没看下一章,模板方法模式是昨天看的。
今天在忙活的事完成了三分之一了,但愿明天能搞出来一个demo。