/** * @author 陈柏宇 * 这个设计模式适合在这样的场景下使用: * 我们想输出一个相同问题的不同答案,那么这个时候只要答案不同就可以了,题目都是相同的 * 所以我们就可以写一个父类,让这个父类在模板方法里写出题干,父类的抽象方法则是子类要去实现的功能 * * 那么我们既然已经使用了继承,并且肯定这个继承有意义,父类就应该要成为子类的模板,所有重复的代码都应该 * 上升到父类中去,而不是让每个子类都重复 * * 我们再来介绍一下模板方法模式: * 定义一个操作中的算法的骨架,并且将一些步骤延迟到子类中去,模板方法让每个子类可以不改变一个算法的结构 * 即可重新定义该算法的某些特定步骤 * * */
模板方法模式简而言之就是提供了一种很好的代码复用平台,当不变的和可变的行为在方法子类实现中混合在一起的时候,不变得行为就会
在子类中重复出现,代码冗余,我们可以通过模板方法模式把不变的搬移到父类中去,通过继承帮助子类摆脱重复的不变行为的纠缠。
这其实在我的项目中也有体现。
我们先看看模板的UML类图:
父类代码:
/** * @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
对继承和多态玩的好的人几乎都会在继承体系中或多或少的使用它,这是一个非常常用的设计模式,希望大家掌握并多多使用!