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

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

模板方法的前提

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

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

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

类图

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

常见案例

    最开始学习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一个匿名内部类,调用一下方法,原来的写的代码都移动到抽象类方法中,提交的代码的变动相对比较少,而且不容易出错,逻辑都在模板里,只要想好一个就可以了。

       

       

 

 

        

         

 

 

223916_bL9y_2663968.jpg
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值