设计模式之模板方法模式

303 阅读4分钟

一、简述

写简历的时候,我们通常会找好一个模板,之后往模板上填充上个人信息、项目信息就构成了自己的简历。这种通过通用格式、通用模板来构建新对象的方式,在编程上就是“模板方法模式”

二、例子

假设这么个场景:我们希望出试卷的老师,能够出一套统一格式的试卷,不管是什么科目,都有选择题、判断题、简答题,那我们就可以使用模版模式。

我们先把模版类定义好

package com.design.template;

public abstract class PaperTemplate {

    /**
     * 选择题
     */
    protected abstract void choiceQuestion();

    /**
     * 判断题
     */
    protected abstract void trueOrFalseQuestion();

    /**
     * 简答题
     */
    protected abstract void shortAnswerQuestion();

    /**
     * 获取整张试卷内容
     */
    public void getTestPaper(){
        choiceQuestion();
        trueOrFalseQuestion();
        shortAnswerQuestion();
    }

}

接下来就通过扩展这个模版来构建具体的试卷、比如数学试卷

package com.design.template;

public class MathPaper extends PaperTemplate {
    @Override
    protected void choiceQuestion() {
        System.out.println("选择题:");
        System.out.println("1、不小于-4的非正整数有()\n" +
                "A、5个    " +
                "B、4个\n" +
                "C、3个    " +
                "D、2个");
        System.out.println("2、如果两个有理数在数轴上的对应点分别在原点的两侧,那么这两个数的商一定是()\n" +
                "A、正数   " +
                "B、负数\n" +
                "C、0   " +
                "D、可能是正数或负数");

    }

    @Override
    protected void trueOrFalseQuestion() {
        System.out.println("判断题:");
        System.out.println("1、两个数的积是正数,那么这两个数的商也是正数     []");
        System.out.println("2、-a一定表示负数。                           []");
    }

    @Override
    protected void shortAnswerQuestion() {
        System.out.println("简答题:");
        System.out.println("1、出租司机小张某天下午的营运全是在到西走向的大街上进行的,若规定向东为正,向西为负,他这天下午行车里程(单位:千米)记录如下:  +8,-3,+15,-10,-13,+3,-15,+11,-12 (7分)\n" +
                "(1)将最后一名乘客送到目的地时,小张距下午出车点的距离是多少千米?\n" +
                "(2)若汽车耗油量为0.08升/千米,这天下午汽车共耗油多少升?");
    }
}

再通过这套模块生成一套化学题

package com.design.template;

public class ChemistryPaper extends PaperTemplate {
    @Override
    protected void choiceQuestion() {
        System.out.println("选择题:");
        System.out.println("1、只发生物理变化的是(  )\n" +
                "A、矿石粉碎   " +
                "B、纸张燃烧\n" +
                "C、光合作用   " +
                "D、铁钉生锈");
        System.out.println("2、下列生活中常见的一些变化,其中属于化学变化的是 (  )\n" +
                "A、夏天雪糕慢慢融化   " +
                "B、潮湿的衣服在空气中变干\n" +
                "C、洗净的铁锅出现锈迹   " +
                "D、夏天从冰箱取出的瓶子外壁附着一层水珠");
    }

    @Override
    protected void trueOrFalseQuestion() {
        System.out.println("判断题:");
        System.out.println("1、果糖、葡萄糖、麦芽糖都是具有甜味的晶体。                []");
        System.out.println("2、淀粉、油脂、蛋白质和纤维素都属于高分子且通常是混合物。    []");
    }

    @Override
    protected void shortAnswerQuestion() {
        System.out.println("推断简答:");
        System.out.println("A、B、C、D、E五种元素中,A的原子中没有中子;B元素的单质能供给动植物呼吸;C是主要存在于人体骨骼和牙齿中的金属元素;D元素的单质在空气中含量最多;E是组成化合物种类最多的元素.请回答下列问题.\n" +
                "(1)A和D的元素符号依次是_____、 ______.\n" +
                "(2)由上述元素组成的两种非金属单质发生反应的化学方程式是                   、            .\n" +
                "(3)由A、B、C三种元素组成的物质与盐酸反应的化学方程式                         .\n" +
                "(4)由A、B、D、E四种元素组成一种盐的化学式         ,该盐的一种用途是      .");
    }
}

接下来就可以使用这些试卷了

public class Main {

    public static void main(String[] args) {
        System.out.println("***********数学题***********");
        PaperTemplate mathPapper = new MathPaper();
        mathPapper.getTestPaper();

        System.out.println("***********化学题***********");
        PaperTemplate chemistryPaper = new ChemistryPaper();
        chemistryPaper.getTestPaper();
    }
}

执行结果


可以看到、通过定义模版,即可统一格式、让所有使用这个模版的试卷具有相同题目类型、相同格式、这就是模版模式。

三、应用

模版模式在Java中有广泛的应用,如ArrayQueue、ArrayList都继承AbstractList、将通用的代码抽象在AbstractList这模版类中。同时通过抽象方法、指定了具体实现类需要实现的方法。

四、总结

1、模版方法模式可以通过模版抽象出一些公共的代码,如上面例子中getTestPaper()方法,这个方法是通用的获取试卷的方法,不需要每份试卷都单独去实现。2、同时模版又给具体实现规范了需实现的内容。如上,规定了每个学科类型试卷都需要有选择、判断、简单题。