设计模式-模板方法模式(Head First)

时间:2022-02-18 05:06:43

参考书籍:Head First设计模式

什么是模板方法模式

定义:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

怎么理解这个定义呢?个人觉得这个定义主要有三个核心的点:

  1. 算法的骨架
  2. 步骤延迟到子类
  3. 子类在不改变算法结构的情况下,重新定义算法的某些步骤

什么是算法的骨架?

设计模式中举的例子是咖啡和茶的例子。冲泡咖啡和茶的流程如下:

冲泡咖啡步骤:把水煮沸----->用沸水冲泡咖啡----->把咖啡倒进杯子----->加糖和牛奶

设计模式-模板方法模式(Head First)

冲泡茶步骤:

把水煮沸----->用沸水浸泡茶叶----->把茶倒进杯子----->加柠檬

设计模式-模板方法模式(Head First)

仔细观察两种方式,发现咖啡和茶的冲泡法大致相同。这时候可以提炼(抽象)出一个冲泡饮品的流程出来,具体流程如下:(好比把大象装进冰箱要三步:1、把冰箱门打开2、把大象塞进去3、关上冰箱门)。

冲泡饮品:把水煮沸----->用热水泡饮品----->把饮料倒进杯子----->在饮料内加入适量的调料

我们把抽象出来的流程放进一个抽象类*其子类(咖啡、茶等)使用,这个冲泡饮品的流程就可以称作为 算法的骨架。一般在抽象类中的表现形式如下:骨架方法 定义为final

 package tudou.javabasic.clone;

 /**
* Created by tudou on 2017-02-23.
*/
public abstract class CaffieineBeverage {
final void prepareRecipe(){
boilWater();
brew();
pourInCup();
addCondiments();
} protected abstract void addCondiments(); private void pourInCup() {
} protected abstract void brew(); private void boilWater() {
}
}

步骤延迟到子类

抽象类中只是对要操作的步骤进行了抽象,并没有全部去具体实现。相同的部分可以实现,例如:把饮品导入杯中(pourInCup)。不同的部分通过具体子类继承来单独实现。

重新定义算法的骨架-使用钩子

钩子是一种被声明在抽象类中的方法,但只有空的或者默认的实现。钩子的存在,可以让子类有能力对算法的不同点进行挂钩。要不要挂钩,由子类自行决定。

设计模式-模板方法模式(Head First)

有了钩子,子类能够决定要不要覆盖方法,如果不提供自己的方法,抽象类会提供一个默认的实现。

例如:Swing窗口程序中的钩子:paint()方法。在默认情况下paint()方法是不做事情的(即空实现)(JFrame的超类Component中对paint()进行了空实现),它是一个“钩子”,通过覆盖paint()方法,我们可以将自己的代码插入到JFrame的算法中,显示出想要的画面。

 public class MyFrame extends JFrame
{
public MyFrame(String titile)
{
super(titile);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setSize(200, 200);
this.setVisible(true);
} @Override
public void paint(Graphics g)
{
super.paint(g);
g.drawString("paint() is a hook", 40, 100);
} public static void main(String[] args)
{
MyFrame f = new MyFrame("swing");
}
}

效果如下:

设计模式-模板方法模式(Head First)