美文网首页
模版模式

模版模式

作者: 笨笨翔 | 来源:发表于2018-09-14 11:49 被阅读0次

    在《JAVA于模式》一书中开头是这样描述模版模式的:

    模板方法模式是类的行为模式。准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后生命一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式的用意。

    模板方法,顾名思义给规定好一个模板,照着完成就好。就好比一种题型,老师告诉你:解题步骤是1:干啥啥,2:干啥啥,3:干啥啥。剩下的只要咱们根据这个模板分别把1、2、3干好就万事大吉来。

    1. 模式结构

    这里涉及到两个角色:

    • 抽象模板角色
    • 具体模板角色


      模板结构

    2. 用例分析

    /**
     * 抽象模板
     */
    public abstract class AbstractTemplate {
        /**
         * 模板方法
         */
        public void templateMethod(){
            //调用基本方法
            abstractMethod();
            hookMethod();
            concreteMethod();
        }
        /**
         * 基本方法的声明(由子类实现)
         */
        protected abstract void abstractMethod();
        /**
         * 基本方法(空方法)  ,钩子方法
         */
        protected void hookMethod(){}
        /**
         * 基本方法(已经实现)
         */
        private final void concreteMethod(){
            //业务相关的代码
        }
    }
    
    /**
     * 具体模板
     */
    public class ConcreteTemplate extends AbstractTemplate{
        //基本方法的实现
        @Override
        public void abstractMethod() {
            //业务相关的代码
        }
        //重写父类的方法,也可以不重写,因父类有默认空实现
        @Override
        public void hookMethod() {
            //业务相关的代码
        }
    }
    

    模板模式的关键是:子类可以置换掉父类的可变部分,但是子类却不可以改变模板方法所代表的顶级逻辑。
    没定义一个新的子类时,不要按照控制流程的思路去想,而应当按照“责任”的思路去想。换言之,应当考虑那些操作是必须置换掉的,那些操作是可以置换掉的,以及那些操作是不可以置换掉的。使用模板模式可以使这些责任变得清晰

    3. 模板模式中的方法

    模板方法中的方法可以分为两大类:模板方法和基本方法。

    • 模板方法
      • 一个模板方法是定义在抽象类中的,把基本操作方法组合在一起形成一个总算法或一个总行为的方法。
      • 一个抽象类可以有任意多个模板方法,而不限于一个。每一个模板方法都可以调用任意多个具体方法。
    • 基本方法
      • 抽象方法: 一个抽象方法由抽象类声明,有具体子类实现
      • 具体方法: 一个具体方法由抽象类声明并实现,而子类并不实现或置换。
      • 钩子方法: 一个钩子方法由抽象类声明并实现,而子类会加以扩展。通常抽象类给出的实现是一个空实现,作为方法的默认实现。

    4. 使用场景

    模板方法在Servlet中的应用

    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
    
            String method = req.getMethod();
    
            if (method.equals(METHOD_GET)) {
                long lastModified = getLastModified(req);
                if (lastModified == -1) {
                    // servlet doesn't support if-modified-since, no reason
                    // to go through further expensive logic
                    doGet(req, resp);
                } else {
                    long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
                    if (ifModifiedSince < (lastModified / 1000 * 1000)) {
                        // If the servlet mod time is later, call doGet()
                        // Round down to the nearest second for a proper compare
                        // A ifModifiedSince of -1 will always be less
                        maybeSetLastModified(resp, lastModified);
                        doGet(req, resp);
                    } else {
                        resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                    }
                }
    
            } else if (method.equals(METHOD_HEAD)) {
                long lastModified = getLastModified(req);
                maybeSetLastModified(resp, lastModified);
                doHead(req, resp);
    
            } else if (method.equals(METHOD_POST)) {
                doPost(req, resp);
                
            } else if (method.equals(METHOD_PUT)) {
                doPut(req, resp);        
                // 省略相关分支代码
            } else {
                //
                // Note that this means NO servlet supports whatever
                // method was requested, anywhere on this server.
                //
    
                String errMsg = lStrings.getString("http.method_not_implemented");
                Object[] errArgs = new Object[1];
                errArgs[0] = method;
                errMsg = MessageFormat.format(errMsg, errArgs);
                
                resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
            }
        }
    
    
    public class TestServlet extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            
            System.out.println("using the GET method");
    
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
                
            System.out.println("using the POST method");
        }
    
    }
    

    参考:java_my_life的模板模式

    相关文章

      网友评论

          本文标题:模版模式

          本文链接:https://www.haomeiwen.com/subject/wizngftx.html