模板方法模式
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。 模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
模式中的角色
- 抽象类(AbstractClass):实现了模板方法,定义了算法的骨架。
- 具体类(ConcreteClass):实现抽象类中的抽象方法,已完成完整的算法。
模板方法应用于下列情况:
一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。
控制子类扩展。模板方法只在特定点调用“ hook”操作 ,这样就只允许在这些点进行扩展。
Servlet是由Tomcat之类的servlet容器来调用处理浏览器请求的,并需要集成基类HttpServlet,如果大家查看HttpServlet源码的时候,就会发现,其实里面有一个
protected void service(HttpServletRequest req, HttpServletResponse resp)方法
servlet容器实际调用的是service方法,service方法的实现就是根据HTTP请求的类型(GET、POST,还是其他),将处理委派给doGet、doPost等方法,由这些子类的方法来最终处理浏览器的请求。
由此可以看出,HttpServlet定义了一个处理的框架或者说模板,实现Servlet只需继承HttpServlet并实现doGet、doPost等方法即可。
现在我们就用模版方法来模拟一下servlet的实现。
模板方法模式的实现
抽象类(AbstractClass):实现了模板方法,定义了算法的骨架。
AbsServlet.java
package com.lingdu.template;
/**
* 2017-3-12
* Servlet的抽象方法
* @author LingDu
*/
public abstract class AbsServlet {
/**
* service方法(相当于定义了一个骨架)
* @param request 需要处理的请求内容
* @param method 请求的方法
* @return
*/
public String service(String request,String method){
if("POST".equals(method)){
return this.doPost(request);
}else if("GET".equals(method)){
return this.doGet(request);
}else{
System.out.println("不支持的方法:" + method);
return "";
}
}
//定义两个未实现的方法
protected abstract String doPost(String request);
protected abstract String doGet(String request);
}
具体类(ConcreteClass):实现抽象类中的抽象方法,已完成完整的算法。
ServletImp.java
package com.lingdu.template;
/**
* 具体的实现类
* @author LingDu
*/
public class ServletImp extends AbsServlet {
/**
* 模拟doPost请求
*/
@Override
protected String doPost(String request) {
System.out.println("doPost:" + request);
return "";
}
/**
* 模拟doGet请求
*/
@Override
protected String doGet(String request) {
System.out.println("doGet:" + request);
return "";
}
}
测试
Test.java
package com.lingdu.template;
public class Test{
public static void main(String[] args) {
//创建servlet对象
ServletImp servletImp = new ServletImp();
//调用service方法,使用POST请求
servletImp.service("使用POST请求", "POST");
//调用service方法,使用GET请求
servletImp.service("使用GET请求", "GET");
}
}