行为型模式-模板方法模式(Template Method)
来源:互联网 发布:谷得网络这家公司怎样 编辑:程序博客网 时间:2024/05/16 07:00
一:定义:
Template Method:Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.
二:引入
一个咖啡店,卖咖啡和茶。
制作咖啡的步骤是:
- 把水煮开。
- 放入咖啡。
- 把煮好的咖啡倒进杯子。
- 加糖或奶。
制作茶的步骤是:
- 把水煮开。
- 放入茶叶。
- 把茶倒进茶杯。
- 加柠檬或其他调料。
public class Coffee ...{
public void prepareRecipe()
...{
boilWater();
brew();
pourInCup();
addCondiments();
}
void boilWater()
...{
System.out.println("boil water");
}
public void brew()
...{
System.out.println("brew coffee");
}
void pourInCup()
...{
System.out.println("pour in cup");
}
public void addCondiments()
...{
System.out.println("add sugar");
}
}
public class Tea ...{
public void prepareRecipe()
...{
boilWater();
brew();
pourInCup();
addCondiments();
}
void boilWater()
...{
System.out.println("boil water");
}
public void brew()
...{
System.out.println("brew tea");
}
void pourInCup()
...{
System.out.println("pour in cup");
}
public void addCondiments()
...{
System.out.println("add lemon");
}
}
public void prepareRecipe()
...{
boilWater();
brew();
pourInCup();
addCondiments();
}
void boilWater()
...{
System.out.println("boil water");
}
public void brew()
...{
System.out.println("brew coffee");
}
void pourInCup()
...{
System.out.println("pour in cup");
}
public void addCondiments()
...{
System.out.println("add sugar");
}
}
public class Tea ...{
public void prepareRecipe()
...{
boilWater();
brew();
pourInCup();
addCondiments();
}
void boilWater()
...{
System.out.println("boil water");
}
public void brew()
...{
System.out.println("brew tea");
}
void pourInCup()
...{
System.out.println("pour in cup");
}
public void addCondiments()
...{
System.out.println("add lemon");
}
}
我们发现,制作两种饮料的方法有些地方是类似的,我们可以对这两个类进行抽象。
public abstract class CaffeineBeverage ...{
public final void prepareRecipe()
...{
boilWater();
brew();
pourInCup();
addCondiments();
}
void boilWater()
...{
System.out.println("boil water");
}
void pourInCup()
...{
System.out.println("pour in cup");
}
abstract void brew();
abstract void addCondiments();
}
public class Coffee extends CaffeineBeverage ...{
public void brew()
...{
System.out.println("brew coffee");
}
public void addCondiments()
...{
System.out.println("add sugar");
}
}
public class Client ...{
public static void main(String[] args) ...{
CaffeineBeverage beverage=new Coffee();
beverage.prepareRecipe();
}
}
public final void prepareRecipe()
...{
boilWater();
brew();
pourInCup();
addCondiments();
}
void boilWater()
...{
System.out.println("boil water");
}
void pourInCup()
...{
System.out.println("pour in cup");
}
abstract void brew();
abstract void addCondiments();
}
public class Coffee extends CaffeineBeverage ...{
public void brew()
...{
System.out.println("brew coffee");
}
public void addCondiments()
...{
System.out.println("add sugar");
}
}
public class Client ...{
public static void main(String[] args) ...{
CaffeineBeverage beverage=new Coffee();
beverage.prepareRecipe();
}
}
父类提供了一个按步骤执行方法的模板,公共部分已经在父类实现,其它由具体子类自己实现。
三:结构
四:实际应用
- javx.servlet.http.HttpServlet
HttpServlet代码,doGet等方法由子类实现。
public abstract class HttpServlet
extends GenericServlet
implements Serializable
...{
protected void service(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException
...{
if(request.getMethod().equals("GET") )
...{
if(testConditional(request,response))
doGet(request,response);
}
else if (request.getMethod().equals("HEAD") )
...{
if(testConditional(request,response))
doHead(request,response);
}
else if (request.getMethod().equals("POST") )
...{
doPost(request,response);
}
else if (request.getMethod().equals("DELETE") )
...{
doDelete(request,response);
}
else if (request.getMethod().equals("OPTIONS") )
...{
doOptions(request,response);
}
else if (request.getMethod().equals("PUT") )
...{
doPut(request,response);
}
else if (request.getMethod().equals("TRACE") )
...{
doTrace(request,response);
}
else
...{
response.sendError(HttpServletResponse.SC_BAD_REQUEST,"Method ""
+request.getMethod()+"" is not supported by this servlet");
}
}
protected void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException
...{
response.sendError(HttpServletResponse.SC_BAD_REQUEST,
"Method "GET" is not supported by this servlet");
}
}
extends GenericServlet
implements Serializable
...{
protected void service(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException
...{
if(request.getMethod().equals("GET") )
...{
if(testConditional(request,response))
doGet(request,response);
}
else if (request.getMethod().equals("HEAD") )
...{
if(testConditional(request,response))
doHead(request,response);
}
else if (request.getMethod().equals("POST") )
...{
doPost(request,response);
}
else if (request.getMethod().equals("DELETE") )
...{
doDelete(request,response);
}
else if (request.getMethod().equals("OPTIONS") )
...{
doOptions(request,response);
}
else if (request.getMethod().equals("PUT") )
...{
doPut(request,response);
}
else if (request.getMethod().equals("TRACE") )
...{
doTrace(request,response);
}
else
...{
response.sendError(HttpServletResponse.SC_BAD_REQUEST,"Method ""
+request.getMethod()+"" is not supported by this servlet");
}
}
protected void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException
...{
response.sendError(HttpServletResponse.SC_BAD_REQUEST,
"Method "GET" is not supported by this servlet");
}
}
一个例子:
public class HelloServlet extends HttpServlet ...{
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
...{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("Hello, World");
out.close();
}
}
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
...{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("Hello, World");
out.close();
}
}
五:适用情形
The Template Method pattern should be used
- to implement the invariant parts of an algorithm once and leave it up to subclasses to implement the behavior that can vary.
- when common behavior among subclasses should be factored and localized in a common class to avoid code duplication. This is a good example of "refactoring to generalize" as described by Opdyke and Johnson [OJ93]. You first identify the differences in the existing code and then separate the differences into new operations. Finally, you replace the differing code with a template method that calls one of these new operations.
- to control subclasses extensions. You can define a template method that calls "hook" operations (see Consequences) at specific points, thereby permitting extensions only at those points.
参考文献:
2:Eric Freeman & Elisabeth Freeman,《Head First Design Pattern》,O'REILLY
3:GOF,《designpatterns-elements.of.reuseable.object-oriented.software》
- Template Method模板方法(行为型模式)
- 行为型模式-模板方法模式(Template Method)
- 设计模式(22)-行为型-模板方法模式(Template Method)
- 行为型模式之模板方法模式(Template Method)
- 行为型模式-----模板方法模式(Template Method)
- [设计模式-行为型]模板方法模式(Template Method)
- 行为型模式-模板方法模式template method
- Template Method 模板方法模式 ----类行为型模式
- 行为模式 - 模板方法(Template Method)
- 行为模式: Template Method(模板方法)
- 模板方法(Template Method)-----类行为型模式
- 模板方法模式Template method(类行为型)
- 模板方法模式Template method(类行为型)
- 模板方法模式Template method(类行为型)
- 3.10 Template Method(模板方法) -- 类行为型模式
- 二十二、模板方法模式Template Method(行为型)
- Template Method模板方法设计模式(类行为型)
- 行为型模式之模板方法TEMPLATE METHOD
- 搞了3个多月,还是没有赚到钱,股市真难。。。。
- Swing程序中关于监听器代码的简化
- 行为型模式-观察者模式(Observer)
- 一种有意思的作图速算法
- Ubuntu的使用经验-持续更新中
- 行为型模式-模板方法模式(Template Method)
- 企业信息化中的“标准”、“行业”和“个性”
- [旧作] 科普还需要普什么?
- AJAX技术之初体验
- 用xmanager连接Linux的配置步骤
- 工作流(Workflow)和BPM的不同
- 在java中对double型运算出现的问题与解决方案
- .Net Remoting Singleton and Singlecall in concurrent enviroment
- 再次的堕落