• 模板方法模式


    每年9月份,大学生开学季,社会主义的接班人们将进入向往的大学学习.....

    大学报到有一个流程,咱们目前就简单分为两步,1.找学校,2.交学费

    任何专业的学生都要执行找学校,但是每个专业的学生的学费价格有所不同

    那我们就来实现大学报到。

    一、报到第一步:找学校。

    报到第一步找学校,这点就不用解释了。。

    public abstract class Register {
        /**
         * 去学校
         */
        public final void goToSchool() {
            System.out.println("大学新生报到:先到学校...");
            pay();//找到学校后就要交学费。。
        }
        /**
         * 交学费
         */
        public abstract void pay();
    }

    此代码pay(交学费)为抽象函数,子类继承实现的时候,重写此函数。然后会在goToSchool中执行此函数。

    二、报到第二步:交学费

    报道完了,就要交学费了。。

    此代码pay(交学费)为抽象函数,子类继承实现的时候,重写此函数。然后会在goToSchool中执行此函数。

    此时,我们定义两个专业的大学生,分别为计算机专业和数学专业。

    因为大学生报到,第一步找学校,肯定是公共的。

    但是,第二步,交学费,就是按照专业的不同,而学费有差异。

    首先定义一个计算机专业的学生

    public class ITStudent extends Register {
    
        @Override
        public void pay() {
            // TODO Auto-generated method stub
            System.out.println("计算机专业学费1万");
        }
    
    }

    然后定义一个,数学专业的学生

    public class MathStudent extends Register {
    
        @Override
        public void pay() {
            // TODO Auto-generated method stub
            System.out.println("数学专业学费5000");
        }
    
    }

    三、实现

    public class Main {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
    
            Register reg = new ITStudent();
            reg.goToSchool();
    
            Register reg1 = new MathStudent();
            reg1.goToSchool();
        }
    
    }

    四、源码实例

     我首先来介绍下,jsp工作机制。

    首先,我有一个index.jsp,访问它时,会在tomcat的work目录中编译成一个index_jsp的类,

    这个index_jsp又继承自抽象类HttpJspBase,抽象类HttpJspBase又继承了Servlet接口。

    首先上HttpJspBase源码

    /*
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    package org.apache.jasper.runtime;
    
    import java.io.IOException;
    
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.jsp.HttpJspPage;
    
    import org.apache.jasper.compiler.Localizer;
    
    /**
     * This is the super class of all JSP-generated servlets.
     *
     * @author Anil K. Vijendran
     */
    public abstract class HttpJspBase extends HttpServlet implements HttpJspPage {
    
        private static final long serialVersionUID = 1L;
    
        protected HttpJspBase() {
        }
    
        @Override
        public final void init(ServletConfig config)
            throws ServletException
        {
            super.init(config);
            jspInit();
            _jspInit();
        }
    
        @Override
        public String getServletInfo() {
            return Localizer.getMessage("jsp.engine.info");
        }
    
        @Override
        public final void destroy() {
            jspDestroy();
            _jspDestroy();
        }
    
        /**
         * Entry point into service.
         */
        @Override
        public final void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
        {
            _jspService(request, response);
        }
    
        @Override
        public void jspInit() {
        }
    
        public void _jspInit() {
        }
    
        @Override
        public void jspDestroy() {
        }
    
        protected void _jspDestroy() {
        }
    
        @Override
        public abstract void _jspService(HttpServletRequest request,
                                         HttpServletResponse response)
            throws ServletException, IOException;
    }

    在抽象类HttpJspBase中看到了实现Servlet接口中的service()方法时,里面放了_jspService(),但是此方法在抽象类中是抽象方法。

    也就是上述方法,是作为模板。因为我们的jsp文件编译成的类(index_jsp),继承了HttpJspBase,所以在类 index_jsp 中,重写_jspService(),

    就可以在Servlet生命周期中的service()函数来调用。

    五、总结

    此设计模式较为简单,一句话总结为:在父类中定义方法(上例中的pay方法),根据不同的子类,延迟在子类中得到不同的实现。

    注意,goToSchool要为final,因为这个方法,不允许被子类重写的。

  • 相关阅读:
    Armijo线性搜索
    numpy 常用工具函数 —— np.bincount/np.average
    理解Buffer
    Node.js 文件系统fs模块
    NodeJS遍历文件生产文件列表
    windows 环境下node开发环境搭配问题
    npm国内镜像
    node+express实现文件上传功能
    Coding 代码管理快速入门(转)
    Node学习HTTP模块(HTTP 服务器与客户端)
  • 原文地址:https://www.cnblogs.com/zh1996/p/10348897.html
Copyright © 2020-2023  润新知