Java设计模式-模板模式
介绍:模板模式定义了一个模板抽象类,这个抽象类中定义了方法调用的形式,顺序。子类通过重写对方法进行实现,但是调用方式不能改变。
模板模式中的模板中定义了核心的代码骨架,一些有着不同方式实现的代码放在子类中,模板模式规定了方法执行的方式或者可以说是方法的执行顺序,执行结构,使得子类只能遵守这些规定。
模板模式解决了很多代码在子类中通用。每次业务相同的代码,用户每次还要重写这些一样的代码,现在将这些通用的代码提取出来,放在一个抽象类中,在抽象类中规定方法执行的方式,一些具体实现不一样的方法定义为抽象方法,由子类通过继承抽象类实现这些抽象方法。也可以说是把通用的算法抽象出来。
把固定的部分封装起来,对于可变的部分用户可以进行扩展,提取出代码的公共部分放在父类,行为由父类控制,子类负责实现可变的部分。
在tomcat中就有模板模式的应用,在用户写的Servlet中的doget和dopost方法就是子类中重写的方法,HttpServlet中的service方法定义了方法执行的方式,以下是HttpServlet中service方法的源码,方法中定义了每个方法执行的顺序,方式。也就是规定了核心,用户需要对那些服务定义自己的代码。
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getMethod();
long lastModified;
if (method.equals("GET")) {
lastModified = this.getLastModified(req);
if (lastModified == -1L) {
this.doGet(req, resp);
} else {
long ifModifiedSince;
try {
ifModifiedSince = req.getDateHeader("If-Modified-Since");
} catch (IllegalArgumentException var9) {
ifModifiedSince = -1L;
}
if (ifModifiedSince < lastModified / 1000L * 1000L) {
this.maybeSetLastModified(resp, lastModified);
this.doGet(req, resp);
} else {
resp.setStatus(304);
}
}
} else if (method.equals("HEAD")) {
lastModified = this.getLastModified(req);
this.maybeSetLastModified(resp, lastModified);
this.doHead(req, resp);
} else if (method.equals("POST")) {
this.doPost(req, resp);
} else if (method.equals("PUT")) {
this.doPut(req, resp);
} else if (method.equals("DELETE")) {
this.doDelete(req, resp);
} else if (method.equals("OPTIONS")) {
this.doOptions(req, resp);
} else if (method.equals("TRACE")) {
this.doTrace(req, resp);
} else {
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[]{method};
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(501, errMsg);
}
}
假设我们去了饭店,干什么,当然是去吃饭喽,我们到饭店吃饭得有个流程吧,首先我们到了饭店,饭店需要为你找座位吧,当你坐下之后,服务员给你一张菜单,让你点菜,这都是固定的顺序,但是你点什么菜不是饭店规定好的,可以随意点,点完之后服务员会把点的这些菜提交给后厨,后厨做好之后服务员端上来,吃完之后就要到前台结账买单。除了顾客点菜之外,剩下的步骤都是一套固定的流程,我们就可以定义一个模板类,规定好饭店的这些流程,只有点餐这个流程不需要具体规定,留给顾客自己选择。
定义模板类:饭店中时规定了方法执行的流程和具体操作,但是顾客点菜是顾客自己的行为,不需要规定
package demo_template;
public abstract class Template {
//服务员为顾客选择座位
private void selectSeat() {
System.out.println("选择一个座位");
}
//服务员给顾客菜单
private void passMenu() {
System.out.println("递菜单");
}
//假设顾客只点了A,B,C三个菜
public abstract void selectA();
public abstract void selectB();
public abstract void selectC();
//服务员提交菜单
private void submitMenu() {
System.out.println("提交菜单");
}
//上菜
private void serving() {
System.out.println("上菜");
}
//顾客买单
private void pay() {
System.out.println("顾客买单");
}
protected void service() {
selectSeat();
passMenu();
this.selectA();
this.selectB();
this.selectC();
submitMenu();
serving();
pay();
}
}
定义第一个顾客:顾客只负责点菜,其他不需要关心
package demo_template;
public class First extends Template {
@Override
public void selectA() {
System.out.println("地三鲜");
}
@Override
public void selectB() {
System.out.println("大米饭");
}
@Override
public void selectC() {
System.out.println("橙汁");
}
}
第二位顾客:
package demo_template;
public class Second extends Template {
@Override
public void selectA() {
System.out.println("大米饭");
}
@Override
public void selectB() {
System.out.println("糖醋鲤鱼");
}
@Override
public void selectC() {
System.out.println("地三鲜");
}
}
测试类:
package demo_template;
public class Test {
public static void main(String[] args) {
System.out.println("第一位顾客:");
Template first = new First();
first.service();
System.out.println("---------------------");
System.out.println("第二位顾客:");
Template second = new Second();
second.service();
}
}
测试类用到了多态,我们创建的对象是First和Second的,类型是Template的,模板类中的三个点菜方法是用的this调用,this代表当前对象,当前对象是谁的,当然是First和Second的。
输出:
第一位顾客:
选择一个座位
递菜单
地三鲜
大米饭
橙汁
提交菜单
上菜
顾客买单
---------------------
第二位顾客:
选择一个座位
递菜单
大米饭
糖醋鲤鱼
地三鲜
提交菜单
上菜
顾客买单
优点:
1、封装不变部分,扩展可变部分。
2、提取公共代码,便于维护。
3、行为由父类控制,子类实现。
缺点:每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。
使用场景:
1、有多个子类共有的方法,且逻辑相同。
2、重要的、复杂的方法,可以考虑作为模板方法。
参考:
http://blog.csdn.net/lovelion/article/details/8299794
http://www.runoob.com/design-pattern/template-pattern.html
Java设计模式-模板模式的更多相关文章
- 【设计模式】Java设计模式 - 模板模式
Java设计模式 - 模板模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起记录分享自己 ...
- 3.java设计模式-建造者模式
Java设计模式-建造者模式 在<JAVA与模式>一书中开头是这样描述建造(Builder)模式的: 建造模式是对象的创建模式.建造模式可以将一个产品的内部表象(internal repr ...
- 12. 星际争霸之php设计模式--模板模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- Java设计模式——组合模式
JAVA 设计模式 组合模式 用途 组合模式 (Component) 将对象组合成树形结构以表示“部分-整体”的层次结构.组合模式使得用户对单个对象和组合对象的使用具有唯一性. 组合模式是一种结构型模 ...
- java设计模式--单列模式
java设计模式--单列模式 单列模式定义:确保一个类只有一个实例,并提供一个全局访问点. 下面是几种实现单列模式的Demo,每个Demo都有自己的优缺点: Demo1: /** * 单列模式需要满足 ...
- Java设计模式-代理模式之动态代理(附源代码分析)
Java设计模式-代理模式之动态代理(附源代码分析) 动态代理概念及类图 上一篇中介绍了静态代理,动态代理跟静态代理一个最大的差别就是:动态代理是在执行时刻动态的创建出代理类及其对象. 上篇中的静态代 ...
- Java设计模式——外观模式
JAVA 设计模式 外观模式 用途 外观模式 (Facade) 为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 外观模式是一种结构型模式. 结构
- 【设计模式】Java设计模式 -工厂模式
[设计模式]Java设计模式 -工厂模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! 目 ...
- 【设计模式】Java设计模式 - 原型模式
[设计模式]Java设计模式 - 原型模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起 ...
随机推荐
- Android可以拖动位置的ListVeiw
参考网址: 1.https://github.com/bauerca/drag-sort-listview 2.http://www.tuicool.com/articles/jyA3MrU
- mysql 查询表死锁 和结束死锁的表步骤
1.查询是否锁表 show OPEN TABLES ; 2.查询进程 show processlist 查询到相对应的进程===然后 kill id 3.查看正在锁的事务 SELECT * FR ...
- JAVA中线程同步方法
JAVA中线程同步方法 1 wait方法: 该方法属于Object的方法,wait方法的作用是使得当前调用wait方法所在部分(代码块)的线程停止执行,并释放当前获得的调用wait所 ...
- lwip Light Weight (轻型)IP协议
wip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈. 外文名 lwip 开发者 瑞典计算机科学院 说 明 Light Weight (轻型)I ...
- Java报SQLException
Java报SQLException 具体错误如下: java.sql.SQLException:Column count doesn't match value count at row 1
- 不同WINDOWS平台下磁盘逻辑扇区的直接读写
不同WINDOWS平台下磁盘逻辑扇区的直接读写 关键字:VWIN32.中断.DeviceIoControl 一.概述 在DOS操作系统下,通过BIOS的INT13.DOS的INT25(绝对读).INT ...
- 手机浏览网页或打开App时莫名弹出支付宝领红包界面的原因及应对措施
自从支付宝推出扫码领红包活动后,这种模式独特的赏金机制,短时间内吸引了大量的关注,但是随之也产生了很多的问题,比由于如在赏金的驱动下,微信群里铺天盖地的红包口令,朋友圈里各式各样的领红包二维码图片, ...
- 【SDOI2009】HH的项链 (莫队)
题面 Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH不断地收集新的贝壳,因此, 他的 ...
- 实战绕过某医院的waf
最近遇到一个注入,我们直接来看吧.还是常规的单引号: 是一个很常规的注入.我们来尝试下获取一些信息: 然后发现是有防火墙的,安全狗.安全狗有很多针对php+mysql的绕过方法,比如这样:/*!uni ...
- java多线程的常见例子
收藏 http://blog.csdn.net/wenzhi20102321/article/details/52524545