这几天遇到了一些事,生活中有太多的不确定性,我所能做的就是做最好的自己。争取能把这本《大话设计模式》的读书笔记做完吧,说真的虽然现在只是Cover到知识点,还并没有实战,不过我想这就是一种积累。就像之前刚阅读完的《深入浅出MySQL》高级部分一样,虽然蛮多还是看不懂,毕竟我不是专业DBA,也没那么多经验。但是知道有这个东西,以后如果遇到了知道该去哪里查,我觉得这也是好的。
今天要介绍的设计模式叫做模板方法模式。说到模板,很多高级的编程语言都有,比如C++有函数模板、类模板;Java有泛型等等。这些模板的作用就是最大化地提高代码的利用率,减少重复写同样的东西,这就应验了编程界的那句Don’t repeat by yourself!
对于这个模板方法模式应用场景,我就用书上的例子吧,真的太形象了!比如考场考试,每一位同学都有一份一模一样的卷子,假设只有选择题,但是每个同学所做的回答却不一样。如果要把这个场景用编程来还原的话,我想最初的思路会是这样的。
import java.util.*;
//同学1回答问题
class Student1
{
public void answer()
{
System.out.println("Q1:What's your favourite star?\nA1:Jessie J");
System.out.println("Q2:Where are you come from?\nA1:China");
System.out.println("Q3:What's your name?\nA1:Jack");
}
}
//同学2回答问题
class Student2
{
public void answer()
{
System.out.println("Q1:What's your favourite star?\nA2:Angela Zhang");
System.out.println("Q2:Where are you come from?\nA2:China");
System.out.println("Q3:What's your name?\nA2:Martin");
}
}
public class Main
{
public static void main(String[] args)
{
Student1 stu1 = new Student1();
System.out.println("这是同学1的作答:");
stu1.answer();
Student2 stu2 = new Student2();
System.out.println("这是同学2的作答");
stu2.answer();
}
}
这里有两个同学,他们分别回答了3个问题,可以发现,重复的代码 实在是太多了。这时我们可以考虑将它们共同的部分(卷子上的题目)进行抽象,变成一个父类,学生继承它回答题目就好了。比如我们可以这样修改代码:
import java.util.*;
//抽象类
abstract class Paper
{
//这个是模板方法,即方法骨架
public void answer()
{
System.out.println("Q1:What's your favourite star?\n"+"A1:"+reply1());
System.out.println("Q2:Where are you come from?\n"+"A2:"+reply2());
System.out.println("Q3:What's your name?\n"+"A3:"+reply3());
}
//方法实现中的某一些细节,因子类不同而不同
protected abstract String reply1();
protected abstract String reply2();
protected abstract String reply3();
}
//同学1回答问题 父类抽象方法具体实现
class Student1 extends Paper
{
protected String reply1()
{
return "Jessie J";
}
protected String reply2()
{
return "China";
}
protected String reply3()
{
return "Jack";
}
}
//同学2回答问题 父类抽象方法具体实现
class Student2 extends Paper
{
protected String reply1()
{
return "Angela Zhang";
}
protected String reply2()
{
return "China";
}
protected String reply3()
{
return "Martin";
}
}
public class Main
{
public static void main(String[] args)
{
//继承、重写、父类引用指向子类对象 =》 多态
Paper p1 = new Student1();
System.out.println("这是同学1的作答:");
p1.answer();
Paper p2 = new Student2();
System.out.println("这是同学2的作答");
p2.answer();
}
}
从以上代码我们不难发现,在父类抽象的时候,把每个问题回答的具体过程变成了一个个返回字符串类型抽象方法,具体方法由子类去实现。这个就叫做模板方法模式。
模板方法模式,定义一个操作中的算法骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。
所以,模板方法模式的核心就是在基类中定义好方法的骨架,让子类在这个骨架下参与方法的某一部分具体实现。
模板方法模式的UML类图如下:
- 另:以上两个程序的最后运行效果是一致的,如下:
这是同学1的作答: Q1:What's your favourite star? A1:Jessie J Q2:Where are you come from? A2:China Q3:What's your name? A3:Jack 这是同学2的作答 Q1:What's your favourite star? A1:Angela Zhang Q2:Where are you come from? A2:China Q3:What's your name? A3:Martin