Servlet与模板方法模式的讲解

开发 后端
我们知道在手写Servlet方法时,会继承父类HttpServlet,这样我们创建的类就会继承HttpServlet,我们知道在HttpServlet中有几个很重要的方法,一个是doPost()方法,一个是doGet()方法,还有一个是Service()方法,当我们在调用自己写的MyServlet方法时,系统会默认调用doGet()方法,为什么呢?

这年头大家都用struts,或者其他MVC框架,很少有人直接用Servlet了吧,但是相信大部分人都应该知道怎么写Servlet的吧,继承 HttpServlet类,覆盖里面的doGet、doPost方法即可,大部分情况下,我们都是对GET和POST一样处理,一般也就这么写了:

 

  1. public MyServlet extends HttpServlet{  
  2.     public void doGet(HttpServletRequest request, HttpServletResponse response){  
  3.         // 处理  
  4.     }  
  5.     public void doPost()HttpServletRequest request, HttpServletResponse response){  
  6.         // 不关心get、post请求,因此post处理直接调用get处理  
  7.         doGet(request, response);  
  8.     }  
  9. }  

Servlet只要在web.xml中部署好之后,就可以处理浏览器的请求了。上面代码可以看出来,doGet方法处理浏览器的GET请求,doPost处理POST请求。

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等方法即可。

是引出模板方法模式定义的时候了,模板方法模式:在一个方法中定义一个算法的骨架,将某些步骤推迟到子类中实现。模板方法允许子类重新定义算法的某些步骤,而不改变算法的结构。

简单UML类图如下:

 

 

简单实现一个抽象类:

 

  1. public abstract Template{  
  2.     public void final templateMethod(){  
  3.         step1();  
  4.         step2();  
  5.         hook();  
  6.     }  
  7.     public abstract void step1();  
  8.     public abstract void step2();  
  9.     public void hook(){}  

这个抽象类,定义了一个算法的骨架,需要step1、step2,都是抽象方法,需要子类来实现。而templateMethod是final的,即不允许子类覆盖。其中定义了方法的步骤,step1、step2。

如下为具体实现:

 

  1. public ConcreteTemplate extends Template{  
  2.     public void step1(){System.out.println("step1");}  
  3.     public void step2(){System.out.println("step2");}  
  4.     public void hook(){System.out.println("hook");}  
  5.     public static void main(String[] args){  
  6.         Template temp = new ConcreteTemplate();  
  7.         temp.templateMethod();  
  8.     }  

可以看到其中加入了一个hook方法,即钩子方法。hook方法在抽象类中的实现为空,是留给子类做一些可选的操作。如果某个子类需要一些特殊额外的操作,则可以实现hook方法,当然也可以完全不用理会,因为hook在抽象类中只是空方法而已。

其他扩展:

1.可以定义多个hook方法

2.hook方法可以定义一个返回为boolean的方法,有子类来决定是否调用hook方法。

eg:抽象类的templateMethod可以这样实现:

 

  1. public void final templateMethod(){  
  2.         step1();  
  3.         step2();  
  4.         if(allowHook())  
  5.             hook();  
  6.     }  
  7.     public boolean allowHook(){return true;}  
  8.     public void hook(){}  

子类中可以覆盖allowHook,以决定是否调用hook方法。

3.抽象类定义的步骤,可以有默认实现,而非全是abstract方法。HttpServlet中已经有doGet、doPost等方法的默认实现,大家可以参考其源码实现。

更好的一个模板方法的例子是Applet,实现自己的Applet,必须继承自Applet,里面实现init、start、stop、destroy等方法即可。这些方法都是有默认实现的,如果看源码,可以发现默认实现其实都是空。

责任编辑:金贺 来源: JavaEye博客
相关推荐

2023-12-12 11:09:55

模板方法模式python设计模式

2009-07-09 16:57:03

Servlet与App

2012-07-11 08:51:51

设计模式

2013-11-26 17:15:13

Android设计模式

2023-05-15 08:38:58

模板方法模式

2009-07-09 11:21:40

Servlet注册

2024-02-21 12:24:33

模板设计模式框架

2009-07-06 16:16:33

Servlet容器工作

2009-07-08 15:59:55

doFilter方法

2009-07-07 16:23:05

Servlet容器

2023-10-27 08:34:46

PythonJava优势

2009-07-08 15:01:00

Servlet的作用

2009-07-08 16:19:41

Servlet ConServlet Con

2009-07-09 14:32:39

2009-06-30 10:33:00

JSP JavaBeaServlet

2009-07-03 17:24:31

Servlet页面跳转

2009-07-03 18:14:27

Servlet线程安全

2009-07-03 13:22:37

调用Servlet

2009-07-06 16:59:16

Servlet方法

2009-07-10 11:07:00

WebWork注入Servlet方法
点赞
收藏

51CTO技术栈公众号