设计模式之模板方法

图1

说明

模板方法模式是行为型设计模式中的一种,在开发中使用的频率相对还是比较高的,主要用来定义一些逻辑的执行流程,也就是算法的骨架。同时呢,模板方法也是相对比较简单的一种设计模式,其涉及的结构,相关的类相较其它的模式来说,比较的少。一般的,只会涉及父类子类这一种关系,父类负责定义算法的骨架,而具体的实现由子类去完成。

模板方法UML图

图1

从图中我们可以看出,模板方法主要由两部分组成:

  1. 抽象模板类: 主要定义算法的结构,也就是业务逻辑的执行流程。这里模板方法里的流程可分为固定的和非固定的两部分,如果是固定的就由抽象类自己去实现,而将非固定的,让子类去实现具体的方法。一般,模板的方法需要使用final来进行修辞,意思是,不能让子类去修改父类模板方法的所定义的业务逻辑。
  2. 具体模板类: 主要是根据具体的类型去实现相应逻辑。子类可以有很多个,每个具体模板类的具体方法实现是不一样的。

模板方法的简单例子

比如,我们手机里通过会下载一些游戏,比如:王者荣耀,魂斗罗…当我们要玩具体某一个游戏的时候,固定的步骤是先打开游戏,然后开始玩游戏,当不想玩的时候,我们会退出游戏,实现上,这就是一个典型的模板方法设计模式的体现。我们下面使用代码的方式来对其进行实现。

抽象模板类

public abstract class AbstractMethodClass {

    /**
     * 定义算法的执行流程
     */
    protected final void templateMethod() {
        openGame();
        playGame();
        exitGame();
    }

    protected abstract void exitGame();

    protected abstract void playGame();

    protected abstract void openGame();

}

通过templateMethod()方法定义了三个抽象方法,分别是打开游戏,玩游戏和退出游戏。而具体打开哪个游戏,怎么玩以及退出哪个游戏我们是不清楚的,只有在玩具体的游戏的时候才能确定。

具体模板类

public class KingGame extends PlayGameClass {
    @Override
    protected void exitGame() {
        System.out.println("退出王者荣耀");
    }

    @Override
    protected void playGame() {
        System.out.println("和兄弟们正在发起对敌人的进攻");

    }

    @Override
    protected void openGame() {
        System.out.println("打开王者荣耀");

    }
}

魂半罗类和此类是类似的代码,就不贴了,这里分别针对不同的游戏来做出了相应的实现。

模板方法的扩展

当在使用模板方法的时候,根据实际情况,我们可以在抽象类中,给相应的方法以默认的实现,可以是空实现或者是一个默认的实现。如果子类 有特殊的需求,可以通过覆盖相对应的方法来更改其实现。 比如:我们在写ListViewadapter时,如果继承自BaseAdapter时,其中的getItemViewTypegetViewTypeCount都是有默认的实现,而如果我们需要在listView中使用多种类型的item的话,就需要覆写这两个方法,来替换父类中的默认实现。

图1

总结

优点

  1. 容易扩展。只需实现相应的抽象方法,就可以针对具体的情况很容易实现功能的扩展。
  2. 便于维护。模板方法统一了业务流程,如果需要对业务流程进行修改,只需要维护模板方法一处地方,而普通的实现,业务逻辑都散落在各个类中,修改起来就比较麻烦。

缺点

  1. 每一个不同的实现都需要新建一个类,会导致类个数的膨胀。

适用场景

  1. 需要统一算法的执行流程时。
  2. 需要对各子类中的行为进行抽象,以避免代码重复时。
  3. 需要控制子类的扩展时。