/**
 * @author 陈柏宇
 * 这个设计模式适合在这样的场景下使用:
 * 我们想输出一个相同问题的不同答案,那么这个时候只要答案不同就可以了,题目都是相同的
 * 所以我们就可以写一个父类,让这个父类在模板方法里写出题干,父类的抽象方法则是子类要去实现的功能
 *
 * 那么我们既然已经使用了继承,并且肯定这个继承有意义,父类就应该要成为子类的模板,所有重复的代码都应该
 * 上升到父类中去,而不是让每个子类都重复
 *
 * 我们再来介绍一下模板方法模式:
 * 定义一个操作中的算法的骨架,并且将一些步骤延迟到子类中去,模板方法让每个子类可以不改变一个算法的结构
 * 即可重新定义该算法的某些特定步骤
 *
 *
 */

模板方法模式简而言之就是提供了一种很好的代码复用平台,当不变的和可变的行为在方法子类实现中混合在一起的时候,不变得行为就会

在子类中重复出现,代码冗余,我们可以通过模板方法模式把不变的搬移到父类中去,通过继承帮助子类摆脱重复的不变行为的纠缠。

这其实在我的项目中也有体现。

我们先看看模板的UML类图:

设计模式----模板方法模式_ide

父类代码:

/**
 * @author 陈柏宇
 * 模板,一切具体事物的父类
 */

public abstract class AbstractClass {
    /**
     * 类中的原始方法
     * 子类都一定要执行的但是都不同的方法
     */
    public abstract void primitiveOperation1();
    public abstract void primitiveOperation2();

    public void TemplateMethod()
    {
        primitiveOperation1();
        primitiveOperation2();
    }
}

子类A代码:

/**
 * @author 陈柏宇
 * 具体子类,继承AbstractClass类并且实现父类中的抽象方法
 *
 */

public class ConcreteClassA extends AbstractClass{

    @Override
    public void primitiveOperation1()
    {
        System.out.println("具体子类A方法1的实现");
    }
    @Override
    public void primitiveOperation2()
    {
        System.out.println("具体子类A方法2的实现");
    }
}

子类B代码:

/**
 * @author 陈柏宇
 * 具体子类B
 */

public class ConcreteClassB extends AbstractClass{
    @Override
    public void primitiveOperation1()
    {
        System.out.println("具体子类B方法1的实现");
    }
    @Override
    public void primitiveOperation2()
    {
        System.out.println("具体子类B方法2的实现");
    }
}

main函数:

public static void main(String[] args) {
        AbstractClass c;

        c = new ConcreteClassA();
        c.TemplateMethod();

        c= new ConcreteClassB();
        c.TemplateMethod();
    }

控制台输出:

具体子类A方法1的实现
具体子类A方法2的实现
具体子类B方法1的实现
具体子类B方法2的实现

我们再来看一个具体的例子:

关于考试。

由于试题都是一样的,而不同的就是学生试卷上写的答案,所以如果我们直接写的话肯定会出现大量代码的冗余

这个时候就要用到我们的模板方法设计模式了:

试卷类:

public abstract class TestPaper {
    public abstract String answer1();

    public abstract String answer2();

    public abstract String answer3();

    public void question1()
    {
        System.out.println("试题1");
        System.out.println("答案:" + answer1());
    }

    public void question2()
    {
        System.out.println("试题2");
        System.out.println("答案:" + answer2());
    }

    public void question3()
    {
        System.out.println("试题3");
        System.out.println("答案:" + answer3());
    }
}

考生A类:

public class TestPaperA extends TestPaper{
    @Override
    public String answer1()
    {
        return "a";
    }
    @Override
    public String answer2()
    {
        return "a";
    }
    @Override
    public String answer3()
    {
        return "a";
    }
}

考生B类:

public class TestPaperB extends TestPaper{
    @Override
    public String answer1()
    {
        return "b";
    }
    @Override
    public String answer2()
    {
        return "b";
    }
    @Override
    public String answer3()
    {
        return "b";
    }
}

main函数:

public static void main(String[] args) {
        System.out.println("学生A的试卷:");
        TestPaper a;
        a = new TestPaperA();
        a.question1();
        a.question2();
        a.question3();

        System.out.println("学生B的试卷");
        TestPaper b;
        b = new TestPaperB();
        b.question1();
        b.question2();
        b.question3();
    }

控制台输出:

学生A的试卷:
试题1
答案:a
试题2
答案:a
试题3
答案:a
学生B的试卷
试题1
答案:b
试题2
答案:b
试题3
答案:b

对继承和多态玩的好的人几乎都会在继承体系中或多或少的使用它,这是一个非常常用的设计模式,希望大家掌握并多多使用!