很多时候我们都在使用模板方法模式而没有意识到自己应经使用了这个模板模式。模板模式是基于继承的代码复用的技术,模板模式的结构和用法也是面向对象的核心。
模板方法模式是类的的行为模式。准备一个抽象类,将部分逻辑以具体方法以及具体构造器的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。
模板方法模式涉及到两个角色:即抽象模板角色和具体模板角色,具体模板角色是对抽象模板角色的继承。
1、抽象模板角色
(1)定义了一个或多个抽象操作,以便子类实现。这些抽象操作叫做原操作或者基本操作,他们是一个顶级逻辑的组成部分。顶级逻辑,即顶级行为的的逻辑,顶级行为,即模板方法所代表的行为。
(2)定义并实现了一个模板方法。这个模板方法一般是一个具体的方法,他给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现,顶级逻辑也有可能调用一些具体的方法,但肯定得有这个抽象模板的抽象方法,否则失去了模板方法模式的意义。
2、具体模板角色
(1)实现父类所定义的一个或多个抽象方法,他们是顶级逻辑的组成部分。
(2)每一个抽象模板角色都可以有任意多个具体模板角色与其对应,而每一个具体模板角色都可以给出抽象模板(即它的抽象的父类)中的抽象方法的不同实现,从而使得顶级逻辑的实现各部相同。
这是一个关于读取的一个例子:我们可以读取一个本地文件,或者是读取一个网页文件内容,它们大体都需要打开、读取、和关闭几个步骤。只不过读取本地文件和读取网页文件的各个步骤不同,所以各个步骤可由具体模板来实现。
抽象模板
public abstract class AbstractRead {
protected String resource;
public void getContent() { // Template Method
if(open()) {
readContent();
close();
}
}
public void setResource(String s) {
resource = s;
}
protected abstract boolean open();
protected abstract void readContent();
protected abstract void close();
}
读取本地文件的具体模板
import java.io.*;
public class ReadFile extends AbstractRead {
private BufferedReader in = null;
public ReadFile() {
}
public ReadFile(String fileName) {
resource = fileName;
}
protected boolean open() {
try {
in = new BufferedReader(new FileReader(resource));
} catch(IOException e) {
System.out.println("Can not open file!");
return false;
}
return true;
}
protected void readContent() {
try {
if(in != null) {
String str;
while((str = in.readLine()) != null) {
System.out.println(str);
}
}
} catch(IOException e) {
System.out.println("Read file error !");
}
}
protected void close() {
if(in != null) {
try {
in.close();
} catch(IOException e) {
System.out.println("IO error !");
}
}
}
}
读取网页文件的具体模板代码
import java.io.*;
import java.net.*;
public class ReadHtml extends AbstractRead {
private URLConnection conn;
private BufferedReader in;
public ReadHtml() {
}
public ReadHtml(String s) {
resource = s;
}
public boolean open() {
try {
URL url = new URL(resource);
conn = url.openConnection();
in = new BufferedReader (
new InputStreamReader(conn.getInputStream()));
} catch (MalformedURLException e) {
System.out.println("Uable to connect URL:" + resource);
return false;
} catch (IOException e) {
System.out.println("IOExeption when connecting to URL" + resource);
return false;
}
return true;
}
protected void readContent() {
try {
if(in != null) {
String str;
while((str = in.readLine()) != null) {
System.out.println(str);
}
}
} catch(IOException e) {
System.out.println("Read file error !");
}
}
protected void close() {
if(in != null) {
try {
in.close();
} catch(IOException e) {
System.out.println("IO error !");
}
}
}
}
接下来是模拟客户端的一个测试类
public class Test {
public static void main(String[] args) {
// 我的文件路径实在linux下,如果是windows下可使用文件的绝对路径即可
String fileName = "/root/test.txt";
String url = "http://java.iteye.com/";
AbstractRead fileRead = new ReadFile();
AbstractRead htmlRead = new ReadHtml();
fileRead.setResource(fileName);
htmlRead.setResource(url);
System.out.println("----- Read from a file -----");
fileRead.getContent();
System.out.println("----- Read from a url -----");
htmlRead.getContent();
}
}
模板方法适用于以下情况:
1) 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
2) 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。其实这可以说是一种好的编码习惯了。
3) 控制子类扩展。模板方法只在特定点调用操作,这样就只允许在这些点进行扩展。比如上面runBare()方法就只在runTest前面适用setUp方法。如果你不愿子类来修改你的模板方法定义的框架,你可以采用两种方式来做:一是在API中不体现出你的模板方法;二、将你的模板方法置为final就可以了。
可以看出,使用模板方法模式可以将代码的公共行为提取出来,达到复用的目的。而且,在模板方法模式中,是由父类的模板方法来控制子类中的具体实现。这样你在实现子类的时候,根本不需要对业务流程有太多的了解。
java语言中使用过的模板方法模式
ClassLoader类,当我们要自定义一个类加载器的时候,我们需要定义一个自己定义一个类加载器,这个类需要继承自这个ClassLoader类,这个类就是抽象模板,在自定一的类加载的中我们只需要在自定义的类加载器的这个类中实现findClass方法即可,
public Class findClass(String name) {
byte[] b = loadClassData(name);
return defineClass(name, b, 0, b.length);
}
类加载器的加载过程是由ClassLoader抽象类定义好的,即抽象模板的顶级行为。关于java类加载的的详细介绍可以参考这篇博文http://idealab.iteye.com/blog/358592
分享到:
相关推荐
本文实例讲述了Android编程设计模式之模板方法模式。分享给大家供大家参考,具体如下: 一、介绍 在面向对象开发过程中,通常会遇到这样的一个问题,我们知道一个算法所需的关键步骤,并确定了这些步骤的执行顺序,...
Java设计模式之模板方法模式.rarJava设计模式之模板方法模式.rar
设计模式之模板方法模式Java实现和UML类设计图
Java设计模式之模板方法模式Java认证考试.pdf
将《Head First 设计模式》(中文版)按章节进行了分割,每章一个文件,方便大家下载。
本文实例讲述了Python设计模式之模板方法模式。分享给大家供大家参考,具体如下: 模板方法模式(Template Method Pattern):定义一个操作中的算法骨架,将一些步骤延迟至子类中.模板方法使得子类可以不改变一个算法的...
本文实例讲述了PHP设计模式之模板方法模式。分享给大家供大家参考,具体如下: 定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 模板...
本文实例讲述了JavaScript设计模式之模板方法模式原理与用法。分享给大家供大家参考,具体如下: 一、模板方法模式:一种只需使用继承就可以实现的非常简单的模式。 二、模板方法模式由两部分组成,第一部分是抽象...
run()方法,这是一个汇总方法,一个模型生产成功了,总要拿给客户检测,run()方法就是一种检验方法,让它跑起来,通过run()方法,把所有功能都测试到了。
本文实例讲述了PHP设计模式之模板方法模式定义与用法。分享给大家供大家参考,具体如下: 什么是模板方法模式 模板方法(Template Method)设计模式中使用了一个类方法templateMethod(), 该方法是抽象类中的一个具体...
主要为大家详细介绍了java设计模式之模板方法模式的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
设计模式的模板方法模式的例子,希望对大家有用~~~~~~~~
主要为大家详细介绍了C++设计模式之模板方法模式TemplateMethod,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
设计模式--模板方法模式java例子
主要介绍了Java经典设计模式之模板方法模式,简单说明了模板方法模式的原理、定义,并结合实例形式分析了java模板方法模式的具体使用方法,需要的朋友可以参考下