设计模式之模板模式
来源:互联网 发布:linux回到根目录 编辑:程序博客网 时间:2024/05/21 06:38
1 概述
模板模式(Template Patern),是在一个方法中定义了一个算法的骨架,而将一些步骤延迟到子类中。模板方法中使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
模板就是一个方法,这个方法将算法定义成一组步骤,为了不被子类改变,这个方法通常被限制为final类型。另外还有一个钩子(hook)的概念,所谓的“钩子”就是默认不做事的方法,这个方法在抽象类中是不实现的或者为空,子类可以决定是否要覆盖它,自然,这个方法的调用是在“模板”方法中。
当子类必须提供“模板”中某个方法的实现时,这个方法就在父类中定义为抽象方法;如果这个方法是可选的,或者对于子类的实现不重要的时候,就使用钩子来控制。使用钩子,可以让子类对模板方法中即将发生的步骤做出反应。
2 示例
来个示例,其实网上很多例子了,做饭的例子、烧菜的例子、泡咖啡泡茶的例子,等等,都是为了说明模板模式的用法。在这里就不说那些例子了,自己写个玩完,纯粹练手。
现在安卓手机应用非常多,但是都需要首先安装到手机上才能使用,在安装的时候,我们抽象一下,一般需要这么几个步骤:申请安装权限、创建相应目录、注册服务、选择是否开机启动等。我们以这个为例子,说明下模板模式的使用。
首先是创建个抽象类,用于描述所有的安装步骤:
1 package org.scott.template; 2 /** 3 * @author Scott 4 * @date 2013年12月25日 5 * @description 6 */ 7 public abstract class Setup { 8 public final void setup(){ 9 getAuthority();10 createDir();11 registerService();12 13 if(isAutoStart()){14 autoStart();15 }16 17 printMsg();18 }19 20 public abstract void getAuthority();21 public abstract void createDir();22 public abstract void registerService();23 24 public boolean isAutoStart(){25 return false;26 };27 28 public void printMsg(){29 System.out.println("The app has set up over.");30 }31 32 private void autoStart(){33 System.out.println("The app will start automatically, has add it to the auto-start list.");34 }35 }
这里的setup方法是final类型的,就是我们上面说的"模板"方法,其中定义了各个算法,就是安装步骤,包括获取权限、创建目录、注册服务、是否开机启动等。是否开机启动这个就是钩子,由子类决定。
下面是具体的一个实现,有道笔记的安装:
1 package org.scott.template; 2 /** 3 * @author Scott 4 * @date 2013年12月25日 5 * @description 6 */ 7 public class YoudaoSetup extends Setup { 8 9 @Override10 public void getAuthority() {11 System.out.println("Has got the set up authority.");12 }13 14 @Override15 public void createDir() {16 System.out.println("Create Youdao directory.");17 }18 19 @Override20 public void registerService() {21 System.out.println("Register the Youdao service.");22 }23 24 @Override25 public boolean isAutoStart() {26 return true;27 }28 29 }
这里的实现,我们覆写了isAutoStart方法,将其设置为true,将当前此软件加入开机自启列表中。钩子,可以在子类中覆写,也可以直接使用父类中的默认实现。下面的QQ安装,就是使用的默认实现:
1 package org.scott.template; 2 /** 3 * @author Scott 4 * @date 2013年12月25日 5 * @description 6 */ 7 public class QQSetup extends Setup { 8 9 @Override10 public void getAuthority() {11 System.out.println("Has got the set up authority.");12 }13 14 @Override15 public void createDir() {16 System.out.println("Create QQ directory.");17 }18 19 @Override20 public void registerService() {21 System.out.println("Register the QQ service.");22 }23 }
以上基本上就是抽象模板和具体模板的实现,模板方法实际上在子类中都没有修改,因为我们把它设置成了final型,子类所修改的就是模板方法中的一些具体的实现算法,比如不同的软件,它的安装目录、注册的服务都是不同,我们把这些都作为抽象方法,子类必须实现自己的特定方法。
写个测试类:
1 package org.scott.template; 2 /** 3 * @author Scott 4 * @date 2013年12月25日 5 * @description 6 */ 7 public class TemplateTest { 8 9 public static void main(String[] args) {10 Setup qqSetup = new QQSetup();11 Setup youdaoSetup = new YoudaoSetup();12 13 qqSetup.setup();14 System.out.println("\n---------------------------\n");15 youdaoSetup.setup();16 }17 18 }
测试结果:
1 Has got the set up authority. 2 Create QQ directory. 3 Register the QQ service. 4 The app has set up over. 5 6 --------------------------- 7 8 Has got the set up authority. 9 Create Youdao directory.10 Register the Youdao service.11 The app will start automatically, has add it to the auto-start list.12 The app has set up over.
3 小结
通过上面的例子,我们可以看到,使用模板方式时,有两个角色:
(1)抽象模板角色:定义了一个或多个抽象操作,以便让子类实现,这些抽象操作称为基本操作。
(2)具体模板角色:实现父类所定义的一个或多个抽象方法。
模板模式主要实现了代码复用,符合开放-封闭原则,因为引入了一个抽象类,所以如果具体实现过多的话,类之间的关系是复杂点。
- 设计模式之模板模式
- 设计模式之模板模式
- 设计模式之模板模式
- 设计模式之模板模式
- 设计模式之模板模式
- 设计模式之模板模式
- 设计模式之模板模式
- 设计模式之 - 模板模式
- 设计模式之模板模式
- 设计模式之模板模式
- 设计模式之模板模式
- 设计模式之模板模式
- 设计模式之模板模式
- 设计模式之模板模式
- 设计模式之模板模式
- 设计模式之模板模式
- 设计模式之模板模式
- 设计模式之模板模式
- Linux下使用system()
- android 设置线程的优先级 (2010-12-09 16:49:34)
- oracle: prompt,set feedback set define说明
- 《Java核心技术》读书笔记:CyclicBarrier的使用示例
- I/O端口和I/O内存
- 设计模式之模板模式
- LeetCode之Linked List Cycle
- 被csdn博客系统郁闷了
- C++关键字列表
- .net中按照比例生成图片
- Linux基础-文件查看
- android---Percel
- HashMap的工作原理
- Leetcode: String to Integer (atoi)