标签:
模板方法模式
在一个算法中定义了一个算法骨架,而将一些算法延迟到子类中。模板方法使得子类可以再不改变算法结构的情况下,重新定义算法中的某些步骤。

一个钩子方法常常由抽象类给出一个空实现作为此方法的默认实现。这种空的钩子方法叫做“Do Nothing Hook”。显然,这种默认钩子方法在缺省适配模式里面已经见过了,一个缺省适配模式讲的是一个类为一个接口提供一个默认的空实现,从而使得缺省适配类的子类不必像实现接口那样必须给出所有方法的实现,因为通常一个具体类并不需要所有的方法。
命名规则是设计师之间赖以沟通的管道之一,使用恰当的命名规则可以帮助不同设计师之间的沟通。
钩子方法的名字应当以do开始,这是熟悉设计模式的Java开发人员的标准做法。在上面的例子中,钩子方法hookMethod()应当以do开头;在HttpServlet类中,也遵从这一命名规则,如doGet()、doPost()等方法。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public abstract class DrinkTemplet {
public void prepareDrink(){//模板方法
boilWater();//烧水
brew();//冲泡
pourIncup();//把饮料倒进杯子中
if(CustomerNeedCondiments()){//钩子函数用来控制 模板中的方法
String answer =getUserInput();
addCodiemnts(answer);
}
}
final void addCodiemnts(String condiments) {
System.out.println("4、把"+condiments+"加入到饮料中!");
}
String getUserInput(){
String answer = "null";
return answer;
}
final void pourIncup() {
System.out.println("3、把开水倒进杯子中!");
}
boolean CustomerNeedCondiments() {//钩子函数
return false;
}
abstract void brew();
final void boilWater() {
System.out.println("1、烧热水!");
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Tea extends DrinkTemplet{//具体的子类
@Override
void brew() {
System.out.println("2、drop tea into the cup");
}
@Override
boolean CustomerNeedCondiments() {
boolean flag =false;
System.out.println("would you like add some codiments in your tea?(y/n)");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
if(br.readLine().startsWith("y")){
flag=true;
}
} catch (IOException e) {
// todo auto-generated catch block
e.printStackTrace();
}
return flag;
}
String getUserInput() {
String answer ="null";
try {
System.out.println("what you want add in your tea?");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
answer =br.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return answer;
}
}
下面是摘自别人的博客中的 模板模式的应用:来源: <http://www.cnblogs.com/java-my-life/archive/2012/05/14/2495235.html>
使用过Servlet的人都清楚,除了要在web.xml做相应的配置外,还需继承一个叫HttpServlet的抽象类。HttpService类提供了一个service()方法,这个方法调用七个do方法中的一个或几个,完成对客户端调用的响应。这些do方法需要由HttpServlet的具体子类提供,因此这是典型的模板方法模式。下面是service()方法的源代码:
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String method = req.getMethod();
if (method.equals(METHOD_GET)) {
long lastModified = getLastModified(req);
if (lastModified == -1) {
// servlet doesn‘t support if-modified-since, no reason
// to go through further expensive logic
doGet(req, resp);
} else {
long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
if (ifModifiedSince < (lastModified / 1000 * 1000)) {
// If the servlet mod time is later, call doGet()
// Round down to the nearest second for a proper compare
// A ifModifiedSince of -1 will always be less
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
}
} else if (method.equals(METHOD_HEAD)) {
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp);
} else if (method.equals(METHOD_POST)) {
doPost(req, resp);
} else if (method.equals(METHOD_PUT)) {
doPut(req, resp);
} else if (method.equals(METHOD_DELETE)) {
doDelete(req, resp);
} else if (method.equals(METHOD_OPTIONS)) {
doOptions(req,resp);
} else if (method.equals(METHOD_TRACE)) {
doTrace(req,resp);
} else {
//
// Note that this means NO servlet supports whatever
// method was requested, anywhere on this server.
//
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[1];
errArgs[0] = method;
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
}
}
当然,这个service()方法也可以被子类置换掉。
下面给出一个简单的Servlet例子:
从上面的类图可以看出,TestServlet类是HttpServlet类的子类,并且置换掉了父类的两个方法:doGet()和doPost()。
public class TestServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("using the GET method");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("using the POST method");
}
}
从上面的例子可以看出这是一个典型的模板方法模式。
HttpServlet担任抽象模板角色
模板方法:由service()方法担任。
基本方法:由doPost()、doGet()等方法担任。
TestServlet担任具体模板角色
TestServlet置换掉了父类HttpServlet中七个基本方法中的其中两个,分别是doGet()和doPost()。
标签:
原文地址:http://www.cnblogs.com/renhq/p/4513801.html