设计模式(七、行为型-模板模式)

目录:

  • 什么是模板模式
  • 为什么要有模板模式
  • 模板模式的实现
  • 具体案例

什么是模板模式

在一个方法中定义算法骨架,并将骨架中的某些步骤推迟到子类实现

为什么要有模板模式

1、它可以让子类在不改变算法整体结构的情况下,重新定义算法中的某些步骤(具体实现)。

2、解决复用扩展问题

模板模式的实现

/**
 * 模板模式代码骨架
 *
 * @author zhoude
 * @date 2020/4/18 10:28
 */
public abstract class AbstractClass {

    /**
     * 这就是模板模式的算法骨架
     */
    public final void templateMethod() {
        // ......
        method1();
        // ......
        method2();
        // ......
    }

    /**
     * 算法骨架的具体步骤
     */
    protected abstract void method1();

    /**
     * 算法骨架的具体步骤
     */
    protected abstract void method2();
}
public class ConcreteClass1 extends AbstractClass {

    @Override
    protected void method1() {

    }

    @Override
    protected void method2() {

    }
}
public class ConcreteClass2 extends AbstractClass {

    @Override
    protected void method1() {

    }

    @Override
    protected void method2() {

    }
}
public class Test {

    public static void main(String[] args) {
        AbstractClass abstractClass = new ConcreteClass1();
        abstractClass.templateMethod();

        AbstractClass abstractClass2 = new ConcreteClass2();
        abstractClass2.templateMethod();
    }
}

具体案例

前面我们说到,模板模式可以解决复用扩展问题,这里我们通过几个案例来简述下。

1、复用:

如Java集合包中的AbstractList的addAll方法就定义了添加一个集合到list中的模板方法。

public boolean addAll(int index, Collection<? extends E> c) {
    rangeCheckForAdd(index);
    boolean modified = false;
    for (E e : c) {
        add(index++, e);
        modified = true;
    }
    return modified;
}
1 public void add(int index, E element) {
2     throw new UnsupportedOperationException();
3 }

虽然他的模板方法没有和上述骨架一样定义成final,但正是这样,子类也可以重写定义addAll的算法骨架。

add方法也没有定义成abstract,而是通过抛出异常的方式,其实这都是一样的,都符合模板模式的思想。

———————————————————————————————————————————————————————

2、扩展:

如servlet,我们知道需要实现一个servlet只要继承HttpServlet并实现doGet和doPost方法就可以了。

而这里的doGet和doPost是servlet算法骨架的扩展点,让客户端自行定义具体的请求执行逻辑。

因servlet的service函数过程这里就不再阐述,有兴趣的小伙伴可以自行翻阅源码。