- 抽象类实现部分逻辑并定义抽象方法迫使子类实现剩余的逻辑,
不同的子类只需完成抽象方法的不同实现,但是整个通用的逻辑已经在父类实现
模板方法使用的频率还是比较多的,比如我们导出一个文件或读取一个文件,总是会按照一定的流程的,比如一定要打开一个文件,最后可能都要关闭文件,可能还要记录一下日志,如果不用模板方法就会发现很多逻辑都要重新一遍,变动起来所有的地方也要改一下,模板方法就是为了解决这种对方法逻辑的共性抽象的.
-
上类图
代码示例:
- 定义模板方法,这是模板方法的核心,里面会完成主要的逻辑骨架
package com.byedbl.template;
/**
* An abstract class which can get content from a file or a HTTP URL
* or other resource
*/
public abstract class AbstractRead {
protected String resource;
/**
* <pre>
* 定义个模板方法,完成功能逻辑骨架,具体实现留到子类去实现
* 完成逻辑的抽象
**/
public void getContent() {
if(open()) {
readContent();
close();
}
}
public void setResource(String s) {
resource = s;
}
/**
* 定义子类需要实现的抽象方法
**/
protected abstract boolean open();
protected abstract void readContent();
protected abstract void close();
}
- 子类实现其需要实现的抽象方法,
package com.byedbl.template;
/**
* A concrete class extends AbstractRead
* This class can read from a file
*/
import org.springframework.util.ClassUtils;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
/**
* 一种实现,读文本
* @author : zengzhijun
* @date : 2018/5/25 13:57
**/
public class ReadFile extends AbstractRead {
private BufferedReader in = null;
public ReadFile() {
}
public ReadFile(String fileName) {
resource = fileName;
}
protected boolean open() {
try {
String file = ClassUtils.getDefaultClassLoader().getResource(this.resource).getFile();
in = new BufferedReader(new FileReader(file));
} 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 !");
}
}
}
}
另一种实现
package com.byedbl.template; /**
* A concrete class extends AbstractRead
* This class can read HTML from a HTTP URL
*/
import java.io.*;
import java.net.*;
/**
* 另一种实现,读URL
* @author : zengzhijun
* @date : 2018/5/25 13:57
**/
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 !");
}
}
}
}
- 客户端调用,客户端调
getContent
方法
package com.byedbl.template;
/**
* A test client
*/
public class Test {
public static void main(String[] args) {
String fileName = "test.txt";
String url = "http://www.baidu.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();
}
}