- 抽象類實(shí)現(xiàn)部分邏輯并定義抽象方法迫使子類實(shí)現(xiàn)剩余的邏輯,
不同的子類只需完成抽象方法的不同實(shí)現(xiàn),但是整個(gè)通用的邏輯已經(jīng)在父類實(shí)現(xiàn)
模板方法使用的頻率還是比較多的,比如我們導(dǎo)出一個(gè)文件或讀取一個(gè)文件,總是會(huì)按照一定的流程的,比如一定要打開(kāi)一個(gè)文件,最后可能都要關(guān)閉文件,可能還要記錄一下日志,如果不用模板方法就會(huì)發(fā)現(xiàn)很多邏輯都要重新一遍,變動(dòng)起來(lái)所有的地方也要改一下,模板方法就是為了解決這種對(duì)方法邏輯的共性抽象的.
-
上類圖
模板方法.png 代碼示例:
- 定義模板方法,這是模板方法的核心,里面會(huì)完成主要的邏輯骨架
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>
* 定義個(gè)模板方法,完成功能邏輯骨架,具體實(shí)現(xiàn)留到子類去實(shí)現(xiàn)
* 完成邏輯的抽象
**/
public void getContent() {
if(open()) {
readContent();
close();
}
}
public void setResource(String s) {
resource = s;
}
/**
* 定義子類需要實(shí)現(xiàn)的抽象方法
**/
protected abstract boolean open();
protected abstract void readContent();
protected abstract void close();
}
- 子類實(shí)現(xiàn)其需要實(shí)現(xiàn)的抽象方法,
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;
/**
* 一種實(shí)現(xiàn),讀文本
* @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 !");
}
}
}
}
另一種實(shí)現(xiàn)
package com.byedbl.template; /**
* A concrete class extends AbstractRead
* This class can read HTML from a HTTP URL
*/
import java.io.*;
import java.net.*;
/**
* 另一種實(shí)現(xiàn),讀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 !");
}
}
}
}
- 客戶端調(diào)用,客戶端調(diào)
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();
}
}