0
点赞
收藏
分享

微信扫一扫

和鲸科技受邀参与湖南省气象信息中心开展人工智能研究型业务支撑平台学术交流

晴儿成长记 03-07 14:00 阅读 2

模板方法模式(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();
    }
}
//具体模板类
public class ConcreteClass1 extends AbstractClass {
    @Override
    protected void doSomething() {
        //业务逻辑
    }

    @Override
    protected void doAnything() {
        //业务逻辑
    }
}
//具体模板类
public class ConcreteClass2 extends AbstractClass {
    @Override
    protected void doSomething() {
        //业务逻辑
    }

    @Override
    protected void doAnything() {
        //业务逻辑
    }
}
public class Client {
    public static void main(String[] args) {
        AbstractClass class1 = new ConcreteClass1();
        AbstractClass class2 = new ConcreteClass2();
        //调用模板方法
        class1.templateMethod();
        class2.templateMethod();
    }
}

工作中遇到场景

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;
}

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();
}
protected void initServletBean() throws ServletException {
}

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;
}

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);
}

举报

相关推荐

0 条评论