模板方法模式是类的行为模式。准备一个抽象类,将部分逻辑以详细方法以及详细构造函数的形式实现。然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类能够以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式的用意。

设计模式
模板方法模式:在一个方法中定义一个算法的框架,而将一些步骤延迟到子类中。模板方法使得子类能够在不改变算法结果的情况下,又一次定义算法中的某些步骤。

模板就是一个方法。这种方法将算法定义成一组步骤。当中的不论什么步骤都能够是抽象的,由子类负责实现。这样能够确保算法的结构保持不变。同一时候由子类提供部分实现。


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

使用钩子的真正目的:
钩子能够让子类实现算法中可选的部分,或者在钩子对于子类的实现并不重要的时候,子类能够对此钩子置之不理。

钩子的还有一个使用方法,是让子类能够有机会对模板方法中某些即将发生的(或刚刚发生的)步骤做出反应。


设计原则
好莱坞原则:别调用我们,我们会调用你。
在好莱坞原则下,我们同意低层组件将自己挂钩到系统之上。可是高层组件会决定什么时候和如何使用这些低层组件。换句话说,高层组件对低层组件的方式是“别调用我们,我们会调用你”。

要点
“模板方法”定义了算法的步骤,把这些步骤的实现延迟到子类中。

模板方法模式为我们提供了一种代码复用的重要技巧。

模板方法的抽象类能够定义详细方法、抽象方法、钩子。
为了防止子类改变模板方法中的算法,我们能够将模板方法声明为final。
策略模式和模板方法模式都是封装算法,前者是使用组合。后者是使用继承。
工厂方法是模板方式的一种特殊版本号。


典型的摸板方法应用
1. HttpServlet技术
2. Swing的窗体程序
3. Applet

模板方法模式:
//声明为抽象类,子类必须实现其操作
public abstract class CaffeineBeverage
{ //声明为final,不希望子类覆盖这种方法
final void prepareRecipe()
{
boilWater();
brew();
pourInCup();
addCondiments();
} //声明为抽象类,子类必须实现其操作
abstract void brew();
abstract void addCondiments(); void boilWater()
{
System.out.println("Boiling water");
} void pourInCup()
{
System.out.println("Pouring into cup");
}
} //extends继承
public class Tea extends CaffeineBeverage {
//须要定义抽象方法
public void brew() {
System.out.println("Steeping the tea");
}
public void addCondiments() {
System.out.println("Adding Lemon");
}
}

使用钩子:
public abstract class CaffeineBeverageWithHook {

	void prepareRecipe() {
boilWater();
brew();
pourInCup();
if (customerWantsCondiments()) {
addCondiments();
}
} abstract void brew(); abstract void addCondiments(); void boilWater() {
System.out.println("Boiling water");
} void pourInCup() {
System.out.println("Pouring into cup");
} //定义了一个缺省实现,子类能够覆盖它。但不见得一定要这么做
boolean customerWantsCondiments() {
return true;
}
} public class CoffeeWithHook extends CaffeineBeverageWithHook { public void brew() {
System.out.println("Dripping Coffee through filter");
} public void addCondiments() {
System.out.println("Adding Sugar and Milk");
} //覆盖了这种方法。提供了自己的功能
public boolean customerWantsCondiments() { //让用户输入对调料的决定
String answer = getUserInput(); if (answer.toLowerCase().startsWith("y")) {
return true;
} else {
return false;
}
} private String getUserInput() {
String answer = null; System.out.print("Would you like milk and sugar with your coffee (y/n)? "); BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
try {
answer = in.readLine();
} catch (IOException ioe) {
System.err.println("IO error trying to read your answer");
}
if (answer == null) {
return "no";
}
return answer;
}
}

《Head First 设计模式》学习笔记——模板方法模式的更多相关文章

  1. Java设计模式学习记录-模板方法模式

    前言 模板方法模式,定义一个操作中算法的骨架,而将一些步骤延迟到子类中.使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤. 模板方法模式 概念介绍 模板方法模式,其实是很好理解的,具体 ...

  2. C#学习笔记-模板方法模式

    题目:同学摘抄老师给的试卷并给出自己的对应的答案. 实现: static void Main(string[] args) { Console.WriteLine("学生甲抄的试卷:&quo ...

  3. 设计模式学习之模板方法模式(TemplateMethod,行为型模式)(9)

    一.什么是模板方法模式 Template Method模式也叫模板方法模式,是行为模式之一,它把具有特定步骤算法中的某些必要的处理委让给抽象方法,通过子类继承对抽象方法的不同实现改变整个算法的行为. ...

  4. Java-马士兵设计模式学习笔记-命令模式

    一.概述 命令模式 二.代码 1.Client.java public class Client { public void request(Server server){ server.addCom ...

  5. Java-马士兵设计模式学习笔记-桥接模式

    一.概述 1.桥接模式的应用情况:(1)两个维度扩展(2)排列组合 二.代码 1.Gift.java public class Gift { protected GiftImpl giftImpl; ...

  6. Java-马士兵设计模式学习笔记-工厂模式-抽象工厂模式

    一.概述 1.抽象工厂:当情况是需要产生一系列产品,若需更换产品,则要求一系列产品一起换,且要控制一系列产品的产生过程,此时可考虑抽象工厂模式.例:小明装修屋子,把电视.冰箱都替换掉,他这次需要把电视 ...

  7. Java-马士兵设计模式学习笔记-工厂模式-简单工厂

    一.概述 1.目标:要控制任意类型交通工具的生产模式 2.目标有两层意思(1)任意类型 (2)生产模式,所以对应的,要这两个层面上抽象(Movable,VehicleFactory),利用接口,实现多 ...

  8. Java-马士兵设计模式学习笔记-策略模式-模拟 Comparator接口

    续上一篇  <Java 模拟 Comparable接口> 一.Teacher类及Student类的比较大小方式是不固定的,比如老师除了比较职称外,还可比较工龄大小,年龄大小等.则定义Com ...

  9. Java-马士兵设计模式学习笔记-迭代器模式-模仿Collectin ArrayList LinckedList

    Java Iterator模式 Java Iterator模式, 模仿Collectin ArrayList LinckedList 一.有如下几个类 1.接口Collection.java 2.接口 ...

随机推荐

  1. 12-UIKit(View绘制、绘制曲线、绘制文字、贴图)

    目录: 1. View绘制 2. 绘制曲线 3. 绘制文字 4. 贴图 回到顶部 1. View绘制 1.1 做出自己的视图对象 TRCell : UITableViewCell : UIView U ...

  2. Cloud Engine

    Cloud Engine:大杀器如何炼成   郑昀 创建于2016/6/18 最后更新于2016/6/19 点击查看我的<如何从零搭建一个技术平台>,这是一个系列.转载时请注明“转载自旁观 ...

  3. 十天学习PHP之第四天

    学习目的:学会连接数据库  PHP简直就是一个函数库,丰富的函数使PHP的某些地方相当简单.建议大家down一本PHP的函数手冊,总用得到. 我这里就简单说一下连接MYSQL数据库.  1.mysql ...

  4. 改动项目APP名字后,在真机执行报错:The provisioning profile specified in your build settings (“haotian”) has an AppI

    错误提醒:The provisioning profile specified in your build settings ("haotian") has an AppID of ...

  5. CentOS桌面环境如何打开终端以及如何将终端加入右键

    安装完CentOS的桌面环境后,默认在桌面以及右键是没有打开终端选项的,要想打开终端,可以由以下步骤: 在左上角菜单[Applications]--->[System Tools]---> ...

  6. 四个流行的Java连接池之Proxool篇

    Proxool是一个JavaSQL Driver驱动程序,提供了对你选择的其它类型的驱动程序的连接池封装.可以非常简单的移植到现存的代码中.完全可配置.快速,成熟,健壮.可以透明地为你现存的JDBC驱 ...

  7. protected的一些功能

    java的访问限制有private.protected.public.这里只想进一步认识一下protected. 我对protected有4个疑问: 1,在相同包中,是否可以调用其它类的protect ...

  8. Andorid时间控件和日期控件

      

  9. PHP把数字ID转字母ID

    PHP把数字ID转字母ID ID是网站中经常出现的,它一般是数字,但是我们发现现在的网站很多ID都是字母了,比如YouTube的视频播放页它的URL类似/watch?v=yzNjIBEdyww. 下面 ...

  10. SharePoint 2013 &quot;通知我&quot;简单的功能

    简单的功能 "通知我"内部列表或文档库中的主要项目.加入/删除/修改等操作,用户的E- mail通知设定功能:设置列表或文档库通知的能力,有可能设置通知为一个单一的项目.这是Sha ...