• 设计模式之模板方法模式


    模板方法模式(Template Method Pattern)

    定义

    定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。

    使用场景

    算法骨架固定,实现细节不一样

    主要角色

    1. 抽象类

      一般方法,可在抽象类中实现,也可以在子类实现

      • 基本方法:doSomething,doAnything 由子类实现的方法,并且在模板方法被调用
      • 模板方法:templateMethod实现对基本方法的调度,完成固定的逻辑
    2. 具体类

    类图

    image-20240105150609197

    示例代码

    //抽象模板类
    public abstract class AbstractClass {
        //基本方法
        protected abstract void doSomething();
    
        //基本方法
        protected abstract void doAnything();
    
        public void templateMethod() {
            //调用基本方法,完成相关逻辑
            this.doAnything();
            this.doSomething();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    //具体模板类
    public class ConcreteClass1 extends AbstractClass {
        @Override
        protected void doSomething() {
            //业务逻辑
        }
    
        @Override
        protected void doAnything() {
            //业务逻辑
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    //具体模板类
    public class ConcreteClass2 extends AbstractClass {
        @Override
        protected void doSomething() {
            //业务逻辑
        }
    
        @Override
        protected void doAnything() {
            //业务逻辑
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    public class Client {
        public static void main(String[] args) {
            AbstractClass class1 = new ConcreteClass1();
            AbstractClass class2 = new ConcreteClass2();
            //调用模板方法
            class1.templateMethod();
            class2.templateMethod();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    工作中遇到场景

    HttpServlet

    public abstract class SimpleHttpServlet extends HttpServlet {
    
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp)
                throws IOException {
            // 模板方法,定义了 HTTP 请求处理的骨架
            if (req.getMethod().equals("GET")) {
                doGet(req, resp);
            } else if (req.getMethod().equals("POST")) {
                doPost(req, resp);
            }
            // 其他 HTTP 方法的处理可以在这里扩展
        }
    
        protected abstract void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException;
    
        protected abstract void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    org.springframework.web.servlet.HttpServletBean#init

    @Override
    public final void init() throws ServletException {
    
        // Set bean properties from init parameters.
        PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
        if (!pvs.isEmpty()) {
            try {
                BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
                ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
                bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
                initBeanWrapper(bw);
                bw.setPropertyValues(pvs, true);
            }
            catch (BeansException ex) {
                if (logger.isErrorEnabled()) {
                    logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
                }
                throw ex;
            }
        }
    
        // Let subclasses do whatever initialization they like.
        initServletBean();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    protected void initServletBean() throws ServletException {
    }
    
    • 1
    • 2

    InputStream

    public abstract class InputStream {
        // 模板方法
        public int read(byte b[], int off, int len) throws IOException {
            // ...
            int c = read();
            // ...
            return c;
        }
    
        // 抽象方法,由子类提供具体实现
        public abstract int read() throws IOException;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    AbstractController

    public abstract class AbstractController implements Controller {
        // 模板方法
        @Override
        protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) {
            // 具体的请求处理逻辑由子类实现
            // ...
            return getModelAndView(request, response);
        }
    
        // 具体的请求处理逻辑由子类实现
        protected abstract ModelAndView getModelAndView(HttpServletRequest request, HttpServletResponse response);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    创建maven的 java web项目
    button样式
    京东按关键词搜索商品列表接口:竞品分析,商品管理,营销策略制定
    Android原生项目集成uniMPSDK(Uniapp)遇到的报错总结
    websocket聊天的功能
    R语言使用MASS包的polr函数构建有序多分类logistic回归模型、使用VGAM包的vglm函数对有序多分类logistic回归模型进行平行性假设作检验
    DataOps不是工具,而是帮助企业实现数据价值的最佳实践
    jenkins如何请求http接口及乱码问题解决
    蓝桥杯物联网竞赛_STM32L071_20_用printf将数据显示在OLED上
    HTML CSS JS 网页设计作业「我的家乡吉林」
  • 原文地址:https://blog.csdn.net/weixin_41883161/article/details/136496846