Servlet與模板方法模式的講解
這年頭大家都用struts,或者其他MVC框架,很少有人直接用Servlet了吧,但是相信大部分人都應(yīng)該知道怎么寫Servlet的吧,繼承 HttpServlet類,覆蓋里面的doGet、doPost方法即可,大部分情況下,我們都是對GET和POST一樣處理,一般也就這么寫了:
- public MyServlet extends HttpServlet{
- public void doGet(HttpServletRequest request, HttpServletResponse response){
- // 處理
- }
- public void doPost()HttpServletRequest request, HttpServletResponse response){
- // 不關(guān)心get、post請求,因此post處理直接調(diào)用get處理
- doGet(request, response);
- }
- }
Servlet只要在web.xml中部署好之后,就可以處理瀏覽器的請求了。上面代碼可以看出來,doGet方法處理瀏覽器的GET請求,doPost處理POST請求。
Servlet是由Tomcat之類的servlet容器來調(diào)用處理瀏覽器請求的,并需要集成基類HttpServlet,如果大家查看HttpServlet源碼的時(shí)候,就會發(fā)現(xiàn),其實(shí)里面有一個(gè)
protected void service(HttpServletRequest req, HttpServletResponse resp)
方法,servlet容器實(shí)際調(diào)用的是service方法,service方法的實(shí)現(xiàn)就是根據(jù)HTTP請求的類型(GET、POST,還是其他),將處理委派給doGet、doPost等方法,由這些子類的方法來最終處理瀏覽器的請求。
由此可以看出,HttpServlet定義了一個(gè)處理的框架或者說模板,實(shí)現(xiàn)Servlet只需繼承HttpServlet并實(shí)現(xiàn)doGet、doPost等方法即可。
是引出模板方法模式定義的時(shí)候了,模板方法模式:在一個(gè)方法中定義一個(gè)算法的骨架,將某些步驟推遲到子類中實(shí)現(xiàn)。模板方法允許子類重新定義算法的某些步驟,而不改變算法的結(jié)構(gòu)。
簡單UML類圖如下:
簡單實(shí)現(xiàn)一個(gè)抽象類:
- public abstract Template{
- public void final templateMethod(){
- step1();
- step2();
- hook();
- }
- public abstract void step1();
- public abstract void step2();
- public void hook(){}
- }
這個(gè)抽象類,定義了一個(gè)算法的骨架,需要step1、step2,都是抽象方法,需要子類來實(shí)現(xiàn)。而templateMethod是final的,即不允許子類覆蓋。其中定義了方法的步驟,step1、step2。
如下為具體實(shí)現(xiàn):
- public ConcreteTemplate extends Template{
- public void step1(){System.out.println("step1");}
- public void step2(){System.out.println("step2");}
- public void hook(){System.out.println("hook");}
- public static void main(String[] args){
- Template temp = new ConcreteTemplate();
- temp.templateMethod();
- }
- }
可以看到其中加入了一個(gè)hook方法,即鉤子方法。hook方法在抽象類中的實(shí)現(xiàn)為空,是留給子類做一些可選的操作。如果某個(gè)子類需要一些特殊額外的操作,則可以實(shí)現(xiàn)hook方法,當(dāng)然也可以完全不用理會,因?yàn)閔ook在抽象類中只是空方法而已。
其他擴(kuò)展:
1.可以定義多個(gè)hook方法
2.hook方法可以定義一個(gè)返回為boolean的方法,有子類來決定是否調(diào)用hook方法。
eg:抽象類的templateMethod可以這樣實(shí)現(xiàn):
- public void final templateMethod(){
- step1();
- step2();
- if(allowHook())
- hook();
- }
- public boolean allowHook(){return true;}
- public void hook(){}
子類中可以覆蓋allowHook,以決定是否調(diào)用hook方法。
3.抽象類定義的步驟,可以有默認(rèn)實(shí)現(xiàn),而非全是abstract方法。HttpServlet中已經(jīng)有doGet、doPost等方法的默認(rèn)實(shí)現(xiàn),大家可以參考其源碼實(shí)現(xiàn)。
更好的一個(gè)模板方法的例子是Applet,實(shí)現(xiàn)自己的Applet,必須繼承自Applet,里面實(shí)現(xiàn)init、start、stop、destroy等方法即可。這些方法都是有默認(rèn)實(shí)現(xiàn)的,如果看源碼,可以發(fā)現(xiàn)默認(rèn)實(shí)現(xiàn)其實(shí)都是空。