模板方法设计模式理论与应用

简介: 首先了解一下什么是模板,在工厂中指定某一样工具的时候,会先设计一个模子,然后就根据这个模子制造成各种颜色的工具。虽然制造出来的工具可能样式、颜色都不同,但是基本的样子和模子是一模一样。抽象到编程中,我们设计一个抽象类模板,指定代码的执行流程,后续子类实现各自的代码逻辑,但是执行流程和抽象父类一样,这种设计模式就是模板方法模式。

听说微信搜索《Java鱼仔》会变更强哦!


本文收录于githubgitee ,里面有我完整的Java系列文章,学习或面试都可以看看哦


(一)什么是模板方法模式(Template method)


首先了解一下什么是模板,在工厂中指定某一样工具的时候,会先设计一个模子,然后就根据这个模子制造成各种颜色的工具。虽然制造出来的工具可能样式、颜色都不同,但是基本的样子和模子是一模一样。


抽象到编程中,我们设计一个抽象类模板,指定代码的执行流程,后续子类实现各自的代码逻辑,但是执行流程和抽象父类一样,这种设计模式就是模板方法模式


(二)模板方法模式中的角色


abstractClass:抽象类


抽象类角色就是上面说的模子,该角色中需要定义抽象方法以及方法执行流程,这些抽象方法由concreteClass具体类实现


concreteClass:具体类


具体类需要继承抽象类,并实现抽象类中的抽象方法,这里实现的方法将会在执行流程中被调用。


(三)代码案例


接下来展示Template method的代码案例。在这段代码中,我会先写一个抽象类,内容是打开冰箱放东西的三大步骤;接着写两个具体类,分别是放水果和放大象。


首先是抽象类:AbstractRefrigerator


publicabstractclassAbstractRefrigerator {
publicabstractvoidopenDoor();
publicabstractvoidputSomething();
publicabstractvoidcloseDoor();
publicfinalvoidexecute(){
openDoor();
putSomething();
closeDoor();
    }
}

在抽象类中,定义了三个抽象方法,分别是打开冰箱门、放入一些东西、关上冰箱门。接着定义一个execute模板方法,指定模板的方法执行流程。 创建第一个具体类PutFruit:

publicclassPutFruitextendsAbstractRefrigerator {
privateStringfruitName;
publicPutFruit(StringfruitName){
this.fruitName=fruitName;
    }
@OverridepublicvoidopenDoor() {
System.out.println("打开冰箱门");
    }
@OverridepublicvoidputSomething() {
System.out.println("放入"+fruitName);
    }
@OverridepublicvoidcloseDoor() {
System.out.println("关上冰箱门");
    }
}

在第一个具体类中,继承了统一的抽象类,并实现三个抽象方法。 创建第二个具体类:PutElephant:

publicclassPutElephantextendsAbstractRefrigerator {
@OverridepublicvoidopenDoor() {
System.out.println("打开冰箱门");
    }
@OverridepublicvoidputSomething() {
System.out.println("放入大象");
    }
@OverridepublicvoidcloseDoor() {
System.out.println("关上冰箱门");
    }
}

最后在main方法中使用两个具体类:

publicclassMain {
publicstaticvoidmain(String[] args) {
AbstractRefrigeratora1=newPutFruit("apple");
a1.execute();
AbstractRefrigeratora2=newPutElephant();
a2.execute();
    }
}

上述每个具体类中都有自己的实现,但是最后执行流程都是按照抽象类中指定的模板规则,这就是模板方法设计模式。


(四)在项目中的应用


我翻了一下目前自己写的项目以及工作中写的项目,发现有一个项目中很巧妙的运用了模板设计模式。因为是工作中的项目,我不会贴代码,讲一下应用场景:


这个项目依赖ES进行数据的查询采集,然后对数据做一些操作加工后返回。这里有一套很规范对模板流程:前置查询参数校验->ES查询->查询后结果处理->封装结果返回


这里的一套流程就被做成了一个抽象类赋予了默认对实现,并提供了一个模板方法按顺序执行上述步骤。后续有新的接口需求就直接按照这套模板流程来。


(五)模板方法模式在源码中的应用


javax.servlet.http.HttpServlet类的实现就使用了模板方法模式。HttpServlet中定义了doGet、doHead、doPost、doPut、doDelete、doOptions、doTrace等方法,并定义了service这个模板方法:


publicabstractclassHttpServletextendsGenericServlet {
protectedvoiddoGet(HttpServletRequestreq, HttpServletResponseresp) throwsServletException, IOException {
//...    }
protectedvoiddoHead(HttpServletRequestreq, HttpServletResponseresp) throwsServletException, IOException {
//...    }
protectedvoiddoPost(HttpServletRequestreq, HttpServletResponseresp) throwsServletException, IOException {
//...    }
protectedvoiddoPut(HttpServletRequestreq, HttpServletResponseresp) throwsServletException, IOException {
//...    }
protectedvoiddoDelete(HttpServletRequestreq, HttpServletResponseresp) throwsServletException, IOException {
//...    }
protectedvoiddoOptions(HttpServletRequestreq, HttpServletResponseresp) throwsServletException, IOException {
//...    }
protectedvoiddoTrace(HttpServletRequestreq, HttpServletResponseresp) throwsServletException, IOException {
//...    }
protectedvoidservice(HttpServletRequestreq, HttpServletResponseresp) throwsServletException, IOException {
Stringmethod=req.getMethod();
longlastModified;
if (method.equals("GET")) {
lastModified=this.getLastModified(req);
if (lastModified==-1L) {
this.doGet(req, resp);
            } else {
longifModifiedSince;
try {
ifModifiedSince=req.getDateHeader("If-Modified-Since");
                } catch (IllegalArgumentExceptionvar9) {
ifModifiedSince=-1L;
                }
if (ifModifiedSince<lastModified/1000L*1000L) {
this.maybeSetLastModified(resp, lastModified);
this.doGet(req, resp);
                } else {
resp.setStatus(304);
                }
            }
        } elseif (method.equals("HEAD")) {
lastModified=this.getLastModified(req);
this.maybeSetLastModified(resp, lastModified);
this.doHead(req, resp);
        } elseif (method.equals("POST")) {
this.doPost(req, resp);
        } elseif (method.equals("PUT")) {
this.doPut(req, resp);
        } elseif (method.equals("DELETE")) {
this.doDelete(req, resp);
        } elseif (method.equals("OPTIONS")) {
this.doOptions(req, resp);
        } elseif (method.equals("TRACE")) {
this.doTrace(req, resp);
        } else {
StringerrMsg=lStrings.getString("http.method_not_implemented");
Object[] errArgs=newObject[]{method};
errMsg=MessageFormat.format(errMsg, errArgs);
resp.sendError(501, errMsg);
        }
    }
}

(六)总结


模板方法设计模式有助于让我们理解抽象类在编程中的含义,其实对很多人而言知道抽象类是什么,但是不理解为什么要使用抽象类。模板方法设计模型就是很好的案例。

相关文章
|
2天前
|
设计模式 安全 数据库连接
后端开发中的设计模式应用
在软件开发的浩瀚海洋中,设计模式如同灯塔,为后端开发者指引方向。它们不仅仅是代码的模板,更是解决复杂问题的智慧结晶。本文将深入探讨几种常见的设计模式,包括单例模式、工厂模式和观察者模式,并揭示它们在实际应用中如何提升代码的可维护性、扩展性和重用性。通过实例分析,我们将一窥这些模式如何在后端开发中大放异彩,助力构建高效、灵活的软件系统。
|
1月前
|
设计模式 消息中间件 缓存
后端开发中的设计模式应用
【8月更文挑战第13天】在软件开发的世界中,设计模式是解决常见问题的最佳实践。对于后端开发者而言,掌握如何将设计模式应用于实际项目不仅可以提高代码质量,还能增强系统的可维护性和扩展性。本文旨在探讨几种常见的设计模式,并解释它们如何优化后端开发流程,提升软件性能和用户体验。
|
2月前
|
设计模式 Java
Java中的设计模式及其应用场景解析
Java中的设计模式及其应用场景解析
|
4天前
|
设计模式 数据库连接 PHP
PHP中的设计模式应用与最佳实践
在本文中,我们将探讨PHP设计模式的应用和最佳实践。通过深入分析,揭示如何在实际项目中有效利用设计模式来优化代码结构、提升系统灵活性和维护性,并分享一些常见设计模式的实际应用案例。无论你是PHP初学者还是经验丰富的开发者,这篇文章都会对你有所帮助。
|
22天前
|
设计模式 算法 开发者
深入理解工厂模式与策略模式:设计模式的灵活应用
深入理解工厂模式与策略模式:设计模式的灵活应用
|
30天前
|
设计模式
设计模式:从理论到实际应用
【8月更文挑战第18天】设计模式是软件工程中解决特定问题的有效方案,提升代码质量并促进团队协作。本文从理论出发,探讨设计模式在实际项目中的应用。设计模式分为创建型、结构型和行为型,遵循如开闭原则等设计原则。通过工厂模式创建不同类型的电子签章,观察者模式实现在状态变更时的通知机制,以及建造者模式灵活组装复杂对象。以虚拟运营商平台为例,采用责任链模式优化审批流程,展示设计模式的实际价值。
|
17天前
|
前端开发 C# 设计模式
“深度剖析WPF开发中的设计模式应用:以MVVM为核心,手把手教你重构代码结构,实现软件工程的最佳实践与高效协作”
【8月更文挑战第31天】设计模式是在软件工程中解决常见问题的成熟方案。在WPF开发中,合理应用如MVC、MVVM及工厂模式等能显著提升代码质量和可维护性。本文通过具体案例,详细解析了这些模式的实际应用,特别是MVVM模式如何通过分离UI逻辑与业务逻辑,实现视图与模型的松耦合,从而优化代码结构并提高开发效率。通过示例代码展示了从模型定义、视图模型管理到视图展示的全过程,帮助读者更好地理解并应用这些模式。
30 0
|
17天前
|
设计模式 安全 数据库连接
|
18天前
|
设计模式 JavaScript 前端开发
从工厂到单例再到策略:Vue.js高效应用JavaScript设计模式
【8月更文挑战第30天】在现代Web开发中,结合使用JavaScript设计模式与框架如Vue.js能显著提升代码质量和项目的可维护性。本文探讨了常见JavaScript设计模式及其在Vue.js中的应用。通过具体示例介绍了工厂模式、单例模式和策略模式的应用场景及其实现方法。例如,工厂模式通过`NavFactory`根据用户角色动态创建不同的导航栏组件;单例模式则通过全局事件总线`eventBus`实现跨组件通信;策略模式用于处理不同的表单验证规则。这些设计模式的应用不仅提高了代码的复用性和灵活性,还增强了Vue应用的整体质量。
13 0
|
27天前
|
设计模式 SQL 缓存
Java编程中的设计模式:单例模式的深入理解与应用
【8月更文挑战第22天】 在Java的世界里,设计模式是构建可维护、可扩展和灵活的软件系统的基石。本文将深入浅出地探讨单例模式这一经典设计模式,揭示其背后的哲学思想,并通过实例演示如何在Java项目中有效运用。无论你是初学者还是资深开发者,这篇文章都将为你打开一扇洞悉软件设计深层逻辑的大门。
26 0