模板方法模式是类的行为模式。准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式的用意。
模板模式的关键是:子类可以置换掉父类的可变部分,但是子类却不可以改变模板方法所代表的顶级逻辑,每当定义一个新的子类时,不要按照控制流程的思路去想,而应当按照“责任”的思路去想。换言之,应当考虑哪些操作是必须置换掉的,哪些操作是可以置换掉的,以及哪些操作是不可以置换掉的。使用模板模式可以使这些责任变得清晰,下面给出一个追求女孩的模板。
Coding:
1、模板类
/** * Java设计模式之模板模式 * * 吖大哥提供了一个文明而向上的追女孩的步骤,具体怎么追怎么才能成功就看你们自己了,健康有效的模板如下 * * @author 吖大哥 * @date Jun 3, 2014 9:25:42 AM */ public abstract class AbstractTemplet { /** 巧遇 */ public abstract void across(); /** 约会 */ public abstract void appointment(); /** 表白 */ public void express() { System.out.println("喜欢你"); } /** 追求 */ public abstract boolean pursuit(); /** 接吻 */ public abstract boolean kissing(); /** 上床 */ public void sleep() { boolean flag1 = pursuit(); boolean flag2 = kissing(); // 吖大哥建议两步成功之后可以考虑上床 if (flag1 && flag2) { System.out.println("你可以和她上床了…………………………………………"); } else if (!flag2 || !flag1) { System.out.println("你追求或者接吻失败啦,你们不能上床…………………………………………"); } } /** 追女孩 */ public final void chasingGirls() {// 使用final关键字锁定子类只能按如下步骤来追女孩 across(); appointment(); express(); sleep(); } }
2、浪漫的追求者类
/** * 浪漫温馨的追求者 * * @author 吖大哥 * @date Jun 3, 2014 10:08:18 AM */ public class RomanticGetGirl extends AbstractTemplet { @Override public void across() { System.out.println("无意间的邂逅"); } @Override public void appointment() { System.out.println("浪漫的约会"); } @Override public boolean kissing() { System.out.println("深情的接吻"); return true; } @Override public boolean pursuit() { System.out.println("缠绵的追求"); return true; } }
3、狂野的追求者类
/** * 狂野的追求者 * * @author 吖大哥 * @date Jun 3, 2014 10:08:42 AM */ public class CrazyGetGirlImpl extends AbstractTemplet { @Override public void across() { System.out.println("疯狂的偶遇"); } /** 表白 */ public void express() { System.out.println("我他妈的贱B嗖嗖的喜欢上你了"); } @Override public void appointment() { System.out.println("疯狂的找人家约会"); } @Override public boolean kissing() { return false; } @Override public boolean pursuit() { return false; } public void sleep() { System.out.println("咱们直接上床吧………………………………"); } }
4、客户端测试
public class Client{ public static void main(String[] args) { AbstractTemplet at1 = new RomanticGetGirl(); at1.chasingGirls(); System.out.println("================================"); AbstractTemplet at2 = new CrazyGetGirlImpl(); at2.chasingGirls(); } }
5、测试结果:
无意间的邂逅 浪漫的约会 喜欢你 缠绵的追求 深情的接吻 你可以和她上床了………………………………………… ================================ 疯狂的偶遇 疯狂的找人家约会 我他妈的贱B嗖嗖的喜欢上你了 咱们直接上床吧………………………………
模板方法模式在Servlet中的应用
使用过Servlet的人都清楚,除了要在web.xml做相应的配置外,还需继承一个叫HttpServlet的抽象类。HttpService类提供了一个service()方法,这个方法调用七个do方法中的一个或几个,完成对客户端调用的响应。这些do方法需要由HttpServlet的具体子类提供,因此这是典型的模板方法模式。下面是service()方法的源代码
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 if (method.equals(METHOD_DELETE)) { doDelete(req, resp); } else if (method.equals(METHOD_OPTIONS)) { doOptions(req,resp); } else if (method.equals(METHOD_TRACE)) { doTrace(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); } }
当然,这个service()方法也可以被子类置换掉。
下面给出一个简单的Servlet例子:
从上面的类图可以看出,TestServlet类是HttpServlet类的子类,并且置换掉了父类的两个方法:doGet()和doPost()。
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"); } }
从上面的例子可以看出这是一个典型的模板方法模式。
HttpServlet担任抽象模板角色
模板方法:由service()方法担任。
基本方法:由doPost()、doGet()等方法担任。
TestServlet担任具体模板角色
TestServlet置换掉了父类HttpServlet中七个基本方法中的其中两个,分别是doGet()和doPost()。
相关推荐
23种设计模式学习笔记及源码,全部原创 欢迎提出意见和建议
Java Design PatternsJava 设计模式学习笔记,简单易懂,每个模式都有相应的代码示列,帮助学习理解。在线阅读地址:设计原则创建型模式作用:将创建与使用代码解耦结构型模式作用:将不同的功能代码解耦桥接模式...
设计模式是一种解决软件设计问题的经验总结,是在软件开发过程中经过反复验证的最佳实践。设计模式提供了一套通用的解决方案,可以帮助开发人员更好地组织和设计代码,提高代码的可读性、可维护性和可扩展性。 设计...
抽象类--模板设计模式 9 接口 9 内部类 11 匿名内部类的使用(重要!!!!!!!) 13 成员内部类的使用 13 静态内部类的使用 14 枚举的二种实现方式 14 自定义类实现枚举 14 使用 enum 关键字实现枚举注意事项 15 enum 用...
Ps:Java设计模式 [设计原则] [单一职责原则] [里氏替换原则] [依赖倒转原则] [接口隔离原则] [迪米特法则] [合成复用原则] 设计模式 创建型模式(5种) 结构型模式(7种) 关系型模式(11种) 适配器模式、装饰模式、代理...
Java Design Patterns 学习笔记 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元...
describe:设计模式学习笔记 逻辑结构图 代码结构图 设计模式简述 创建型模式,共五种:工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。 结构型模式,共七种:适配器模式,装饰器模式,代理模式,...
避坑笔记2021CICDCI/CD流程以及原理说明设计模式:策略模式单例模式工厂模式装饰器模式观察者模式适配器模式模板方法模式SpringBoot:SpringBoot(1):公共配置SpringBoot(2):generatorSpringBoot(3):docker部署...
Struts2 是一个非常优秀的MVC框架,基于Model2 设计模型 由传统Struts1和WebWork两个经典框架发展而来 Struts2框架=Struts2+XWork Strust2 核心功能 允许POJO(Plain Old Java Objects,简单javabean对象,没有继承,...
第一部分:设计模式 & UML 简单工厂 工厂方法模式 抽象工厂模式 策略模式 责任链模式 命令模式 模板方法模式 适配器模式 代理模式 外观模式 组合模式 装饰模式 享元模式 桥接模式 Builder模式 状态模式 解释器模式 ...
VS2005 ASP.NET本地化学习笔记&感受 在自定义Server Control中捆绑JS文件 Step by Step 深度解析Asp.Net2.0中的Callback机制 使用 Web 标准生成 ASP.NET 2.0 Web 站点 ASP.NET 2.0基于SQLSERVER 2005的aspnetdb.mdf...
1、设计模式:模板方法 2、算法:学习动态规范,刷题最长回文数,最长公共子串,爬楼梯 3、kafka:kafka兼顾性能和高可用的实现逻辑 1、Springboot项目部署阿里云,Vue打包App 2、解决Ubuntu18设置mysql的sql_mode...
“基于Spring Boot开发的校园资料分享平台”这一毕业设计项目,不仅展示了Java编程语言的强大功能与灵活性,也充分体现了Spring Boot框架在快速构建Web应用方面的优势。此项目旨在构建一个便于校园内师生共享学习...
:详细的介绍了各种设计模式 :Java、Python等技术 :在线学习、练习 Git 命令,就像打游戏一样 :以大图的方式介绍 Git 命令 :英语听力逐句精听,包含各种类型的听力材料 :在线背单词网站,页面简洁 实用网站 :...
设计模式 LeetCode 面试题 博客和wiki收藏 代码实现 Android javaEE 前端 开源项目收集 JAVAEE 权限引擎 验证码 分布式框架 模板引擎 依赖注入 ORM 日志 搜索引擎 爬虫 数据校验 restful 消息中间件 响应式编程 热...
设计模式 LeetCode 面试题 博客和wiki收藏 代码实现 Android javaEE 前端 开源项目收集 JAVAEE 权限引擎 验证码 分布式框架 模板引擎 依赖注入 ORM 日志 搜索引擎 爬虫 数据校验 restful 消息中间件 响应式编程 热...