实用的设计模式--模板方法模式


声明:本文转载自https://my.oschina.net/xpbob/blog/1550889,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

       模板方法模式是我工作中用到最多的模式,这个模式的类图比较简单,而且思路也比较简单,只要有重复的工作,加以抽象,都可以使用模板方法。

模板方法的前提

        道理很好讲,但是很多人依旧会问,为什么他的编码环境却没有这样的使用情况。

       设计模式是基于面向对象的套路,所以脱离不了抽象这个概念,很多情况之所以没办法去模式化主要是因为无法抽象。

       我们做一件事情,都是分步骤的,例如去煮咖啡,先准备咖啡,然后水加热,放咖啡豆,结束后装入容器。针对这件事情,并不能有什么想法,抽象的基础是找共同点,起码是两个事物之间的影响的结果,如果还有一件事情是煮茶叶,那么过程就是准备茶叶,然后水加热,放茶叶,结束后装入容器。那么明显可以抽象煮东西的这个过程。准备材料,水加热,放材料,结束后装入容器。但是另外一件事情是砍柴,那么这样貌似就不好找细节上的共同点了。很多情况下,没有模式主要是场景的问题,编码就写一个场景,共同点不好找,纯粹靠想象去抽象,可能模式是用上了,但是没有普及性。效果基本和没有模式差不多。

类图

     模板方法模式的主要的思想就是定制一个流程,每个实现类都去遵循这个流程。这个流程是需要通过具体场景去抽象的。

常见案例

    最开始学习web编程的时候都会接触HttpServlet,写自己的servlet的时候,要继承这个类,去重写doget和dopost。这里用的就是模板方法模式。具体的流程就在service方法中。

  protected void service(HttpServletRequest req, HttpServletResponse resp)     throws ServletException, IOException   {     String method = req.getMethod();     //get     if (method.equals("GET"))     {       long lastModified = getLastModified(req);       if (lastModified == -1L)       {         doGet(req, resp);       }       else       {         long ifModifiedSince;         try         {           ifModifiedSince = req.getDateHeader("If-Modified-Since");         }         catch (IllegalArgumentException iae)         {           long ifModifiedSince;           ifModifiedSince = -1L;         }         if (ifModifiedSince < lastModified / 1000L * 1000L)         {           maybeSetLastModified(resp, lastModified);           doGet(req, resp);         }         else         {           resp.setStatus(304);         }       }     }     //head     else if (method.equals("HEAD"))     {       long lastModified = getLastModified(req);       maybeSetLastModified(resp, lastModified);       doHead(req, resp);     }     //post     else if (method.equals("POST"))     {       doPost(req, resp);     }     //put     else if (method.equals("PUT"))     {       doPut(req, resp);     }     //delete     else if (method.equals("DELETE"))     {       doDelete(req, resp);     }     //options     else if (method.equals("OPTIONS"))     {       doOptions(req, resp);     }     //trace     else if (method.equals("TRACE"))     {       doTrace(req, resp);     }     else     {       String errMsg = lStrings.getString("http.method_not_implemented");       Object[] errArgs = new Object[1];       errArgs[0] = method;       errMsg = MessageFormat.format(errMsg, errArgs);              resp.sendError(501, errMsg);     }   }

    在service中对http支持的7中方式都做了处理,剩下的就是每个servlet根据自己的情况覆写doGet,doHead,doPost,doPut,doDelete,doOptions,doTrace。具体的业务也写在具体的方法里,具体是调用的是哪种请求方法由service方法中确认。

思想类似的产物

    java的jdbc的操作都是获取连接,创建statment或者preparestatement,然后执行sql,然后关闭resultset(如果有的话),关闭statement,然后关闭连接。具体和业务相关的其实就是sql,剩下的都是流程化的过程。spring jdbc template就是模板化了这些过程,不同的是,他使用了组合的方式去调用而不是继承,严格意义上不是标准的模板方法,只能说是思想类似。

实战场景

工作中遇到一个场景就是用模板方法来做一个try catch的异常模板。

场景

      最开始写的代码出现一个问题,就是有异常没有处理的话,逻辑都被中断了。因此需要加入异常处理。要这样改的地方还有很多。

代码模板

 public class Template {  	public static void main(String[] args) { 		 		new ExceptionTemplate(){ 			@Override 			protected void toDo() { 				//流程 				System.out.println("over"); 			} 		}.doWork();  	}  } //模板类 abstract class ExceptionTemplate{ 	public final void doWork(){ 		 try{ 			 toDo(); 		 }catch(Exception e){ 			 //异常处理方式 		 } 		 	} 	protected  void toDo(){} }

好处

       每个地方的改动都是有限的,都是new一个匿名内部类,调用一下方法,原来的写的代码都移动到抽象类方法中,提交的代码的变动相对比较少,而且不容易出错,逻辑都在模板里,只要想好一个就可以了。

       

       

 

 

        

         

 

 

本文发表于2017年10月16日 10:39
(c)注:本文转载自https://my.oschina.net/xpbob/blog/1550889,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 1974 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1