模版模式

在《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的模板模式

最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 设计模式概述 在学习面向对象七大设计原则时需要注意以下几点:a) 高内聚、低耦合和单一职能的“冲突”实际上,这两者...
    彦帧阅读 3,942评论 0赞 14
  • 设计模式汇总 一、基础知识 1. 设计模式概述 定义:设计模式(Design Pattern)是一套被反复使用、多...
    MinoyJet阅读 4,159评论 1赞 15
  • 设计模式之Template模式(模版模式)
    南乡清水阅读 679评论 0赞 3
  • 模板方法模式的核心思想就是通过把不变的行为搬移到超类,去除子类中的重复代码来体现它的优势。其实,模板方法模式就是提...
    泥孩儿0107阅读 256评论 0赞 0
  • wx.request({ url: url+'/ttxs/upgrade/getApkVersion.do? ...
    郝赫阅读 482评论 0赞 0

友情链接更多精彩内容