继续设计模式~ 模版方法模式

老套路,先看下定义:定义了一个算法的骨架,而将一些步骤延迟到子类中,模版方法使得子类可以在不改变算法结构的情况下,重新定义算法的步骤。

简单看下定义,模版方法定义了一个算法的步骤,并且允许子类为一个或多个步骤提供实现。定义还算清晰,下面来个例子展示下本公司的上班情况(纯属娱乐,如有雷同,请对号入座)。简单描述一下:本公司有程序猿、测试、HR、项目经理等人,下面使用模版方法模式,记录下所有人员的上班情况:

首先来个超类,超类中定义了一个workOneDay方法,设置为作为算法的骨架:

package com.zhy.pattern.template;public abstract class Worker
{protected String name;public Worker(String name){this.name = name;}/*** 记录一天的工作*/public final void workOneDay(){System.out.println("-----------------work start ---------------");enterCompany();computerOn();work();computerOff();exitCompany();System.out.println("-----------------work end ---------------");}/*** 工作*/public abstract void work();/*** 关闭电脑*/private void computerOff(){System.out.println(name + "关闭电脑");}/*** 打开电脑*/private void computerOn(){System.out.println(name + "打开电脑");}/*** 进入公司*/public void enterCompany(){System.out.println(name + "进入公司");}/*** 离开公司*/public void exitCompany(){System.out.println(name + "离开公司");}}

定义了一个上班(算法)的骨架,包含以下步骤:

a、进入公司

b、打开电脑

c、上班情况

d、关闭电脑

e、离开公司

可以看到,a、b、d、e我们在超类中已经实现,子类仅实现work这个抽象方法,记录每天的上班情况。下面各类屌丝入场:

程序猿:

package com.zhy.pattern.template;public class ITWorker extends Worker
{public ITWorker(String name){super(name);}@Overridepublic void work(){System.out.println(name + "写程序-测bug-fix bug");}}

HR:

package com.zhy.pattern.template;public class HRWorker extends Worker
{public HRWorker(String name){super(name);}@Overridepublic void work(){System.out.println(name + "看简历-打电话-接电话");}}

测试人员:

package com.zhy.pattern.template;public class QAWorker extends Worker
{public QAWorker(String name){super(name);}@Overridepublic void work(){System.out.println(name + "写测试用例-提交bug-写测试用例");}}

项目经理:

package com.zhy.pattern.template;public class ManagerWorker extends Worker
{public ManagerWorker(String name){super(name);}@Overridepublic void work(){System.out.println(name + "打dota...");}}

下面我们测试下:

package com.zhy.pattern.template;public class Test
{public static void main(String[] args){Worker it1 = new ITWorker("鸿洋");it1.workOneDay();Worker it2 = new ITWorker("老张");it2.workOneDay();Worker hr = new HRWorker("迪迪");hr.workOneDay();Worker qa = new QAWorker("老李");qa.workOneDay();Worker pm = new ManagerWorker("坑货");pm.workOneDay();}
}

输出结果:

-----------------work start ---------------
鸿洋进入公司
鸿洋打开电脑
鸿洋写程序-测bug-fix bug
鸿洋关闭电脑
鸿洋离开公司
-----------------work end ---------------
-----------------work start ---------------
迪迪进入公司
迪迪打开电脑
迪迪看简历-打电话-接电话
迪迪关闭电脑
迪迪离开公司
-----------------work end ---------------
-----------------work start ---------------
老李进入公司
老李打开电脑
老李写测试用例-提交bug-写测试用例
老李关闭电脑
老李离开公司
-----------------work end ---------------
-----------------work start ---------------
坑货进入公司
坑货打开电脑
坑货打dota...
坑货关闭电脑
坑货离开公司
-----------------work end ---------------

好了,恭喜你,又学会一个设计模式,模版方法模式。

下面看下模版方法模式类图,和我们程序的类图:

模版方式里面也可以可选的设置钩子,比如现在希望记录程序员离开公司的时间,我们就可以在超类中添加一个钩子:

public boolean isNeedPrintDate(){return false;}/*** 离开公司*/public void exitCompany(){if (isNeedPrintDate()){System.out.print(new Date().toLocaleString()+"-->");}System.out.println(name + "离开公司");}

超类中添加了一个isNeedPrintDate方法,且默认返回false,不打印时间。如果某子类需要调用打印时间,可以复写改钩子方法,返回true,比如,程序猿复写了这个方法:

package com.zhy.pattern.template;public class ITWorker extends Worker
{public ITWorker(String name){super(name);}@Overridepublic void work(){System.out.println(name + "写程序-测bug-fix bug");}@Overridepublic boolean isNeedPrintDate(){return true;}}

最后再看下测试结果:

-----------------work start ---------------
鸿洋进入公司
鸿洋打开电脑
鸿洋写程序-测bug-fix bug
鸿洋关闭电脑
2014-5-19 19:17:05-->鸿洋离开公司
-----------------work end ---------------

好了,关于钩子,超类中可提供默认实现或者空实现,子类可覆盖或者不覆盖,具体根据需求来定。

最近恰好,再写一个爬虫程序,用到了模版方法模式,给大家分享下:

需求分析:程序需要对特定的20个网站进行抓取数据;每个网站页面返回的结果数据不同,url不同,参数不同等;但是抓取的过程是一致的。

于是我就这样的设计:

a、定义一个规则Rule类(包含了:url,params,request_method,以及返回哪块数据【根据选择器】)

b、通过Rule进行抓取数据

c、对数据进行处理

我把上面3个步骤定义了算法的骨架,b为超类实现,a、c由子类实现:

package com.zhy.pattern.template;public abstract class AbsExtractInfo
{/*** 抓取的算法骨架*/public void extract(){Rule rule = generateRule() ;List<Element> eles = getInfosByRule(rule);dealResult(eles);}/*** 生成一个Rule* @return*/public abstract Rule generateRule();/*** 抓取的实现* @param rule* @return*/private List<Element> getInfosByRule(Rule rule){// the implements omitted
    }/*** 处理抓取的结果* @param results*/public void dealResult(List<Element> results);
}

其中GenerateRule这个方法,恰好是工厂模式中的抽象方法模式(定义一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法模式把类实例化的过程推迟到子类),如果你忘记了,可以查看设计模式 工厂模式 从卖肉夹馍说起

好了,就到这里,最后欢迎大家留言。

[java] view plaincopy
  1. package com.zhy.pattern.template;
  2. public class QAWorker extends Worker
  3. {
  4. public QAWorker(String name)
  5. {
  6. super(name);
  7. }
  8. @Override
  9. public void work()
  10. {
  11. System.out.println(name + "写测试用例-提交bug-写测试用例");
  12. }
  13. }

项目经理:

[java] view plaincopy
  1. package com.zhy.pattern.template;
  2. public class ManagerWorker extends Worker
  3. {
  4. public ManagerWorker(String name)
  5. {
  6. super(name);
  7. }
  8. @Override
  9. public void work()
  10. {
  11. System.out.println(name + "打dota...");
  12. }
  13. }

下面我们测试下:

[java] view plaincopy
  1. package com.zhy.pattern.template;
  2. public class Test
  3. {
  4. public static void main(String[] args)
  5. {
  6. Worker it1 = new ITWorker("鸿洋");
  7. it1.workOneDay();
  8. Worker it2 = new ITWorker("老张");
  9. it2.workOneDay();
  10. Worker hr = new HRWorker("迪迪");
  11. hr.workOneDay();
  12. Worker qa = new QAWorker("老李");
  13. qa.workOneDay();
  14. Worker pm = new ManagerWorker("坑货");
  15. pm.workOneDay();
  16. }
  17. }

输出结果:

[java] view plaincopy
  1. -----------------work start ---------------
  2. 鸿洋进入公司
  3. 鸿洋打开电脑
  4. 鸿洋写程序-测bug-fix bug
  5. 鸿洋关闭电脑
  6. 鸿洋离开公司
  7. -----------------work end ---------------
  8. -----------------work start ---------------
  9. 迪迪进入公司
  10. 迪迪打开电脑
  11. 迪迪看简历-打电话-接电话
  12. 迪迪关闭电脑
  13. 迪迪离开公司
  14. -----------------work end ---------------
  15. -----------------work start ---------------
  16. 老李进入公司
  17. 老李打开电脑
  18. 老李写测试用例-提交bug-写测试用例
  19. 老李关闭电脑
  20. 老李离开公司
  21. -----------------work end ---------------
  22. -----------------work start ---------------
  23. 坑货进入公司
  24. 坑货打开电脑
  25. 坑货打dota...
  26. 坑货关闭电脑
  27. 坑货离开公司
  28. -----------------work end ---------------

好了,恭喜你,又学会一个设计模式,模版方法模式。

下面看下模版方法模式类图,和我们程序的类图:

模版方式里面也可以可选的设置钩子,比如现在希望记录程序员离开公司的时间,我们就可以在超类中添加一个钩子:

[java] view plaincopy
  1. public boolean isNeedPrintDate()
  2. {
  3. return false;
  4. }
  5. /**
  6. * 离开公司
  7. */
  8. public void exitCompany()
  9. {
  10. if (isNeedPrintDate())
  11. {
  12. System.out.print(new Date().toLocaleString()+"-->");
  13. }
  14. System.out.println(name + "离开公司");
  15. }

超类中添加了一个isNeedPrintDate方法,且默认返回false,不打印时间。如果某子类需要调用打印时间,可以复写改钩子方法,返回true,比如,程序猿复写了这个方法:

[java] view plaincopy
  1. package com.zhy.pattern.template;
  2. public class ITWorker extends Worker
  3. {
  4. public ITWorker(String name)
  5. {
  6. super(name);
  7. }
  8. @Override
  9. public void work()
  10. {
  11. System.out.println(name + "写程序-测bug-fix bug");
  12. }
  13. @Override
  14. public boolean isNeedPrintDate()
  15. {
  16. return true;
  17. }
  18. }

最后再看下测试结果:

[java] view plaincopy
  1. -----------------work start ---------------
  2. 鸿洋进入公司
  3. 鸿洋打开电脑
  4. 鸿洋写程序-测bug-fix bug
  5. 鸿洋关闭电脑
  6. 2014-5-19 19:17:05-->鸿洋离开公司
  7. -----------------work end ---------------

好了,关于钩子,超类中可提供默认实现或者空实现,子类可覆盖或者不覆盖,具体根据需求来定。

最近恰好,再写一个爬虫程序,用到了模版方法模式,给大家分享下:

需求分析:程序需要对特定的20个网站进行抓取数据;每个网站页面返回的结果数据不同,url不同,参数不同等;但是抓取的过程是一致的。

于是我就这样的设计:

a、定义一个规则Rule类(包含了:url,params,request_method,以及返回哪块数据【根据选择器】)

b、通过Rule进行抓取数据

c、对数据进行处理

我把上面3个步骤定义了算法的骨架,b为超类实现,a、c由子类实现:

[java] view plaincopy
  1. package com.zhy.pattern.template;
  2. public abstract class AbsExtractInfo
  3. {
  4. /**
  5. * 抓取的算法骨架
  6. */
  7. public void extract()
  8. {
  9. Rule rule = generateRule() ;
  10. List<Element> eles = getInfosByRule(rule);
  11. dealResult(eles);
  12. }
  13. /**
  14. * 生成一个Rule
  15. * @return
  16. */
  17. public abstract Rule generateRule();
  18. /**
  19. * 抓取的实现
  20. * @param rule
  21. * @return
  22. */
  23. private List<Element> getInfosByRule(Rule rule)
  24. {
  25. // the implements omitted
  26. }
  27. /**
  28. * 处理抓取的结果
  29. * @param results
  30. */
  31. public void dealResult(List<Element> results);
  32. }

其中GenerateRule这个方法,恰好是工厂模式中的抽象方法模式(定义一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法模式把类实例化的过程推迟到子类),如果你忘记了,可以查看设计模式 工厂模式 从卖肉夹馍说起

好了,就到这里,最后欢迎大家留言。

25
1
  • 上一篇设计模式 外观模式 一键电影模式
  • 下一篇设计模式 状态模式 以自动售货机为例

我的同类文章

【Java 设计模式】(9)
  • •设计模式 状态模式 以自动售货机为例2014-05-20阅读6819
  • •设计模式 适配器模式 以手机充电器为例2014-05-14阅读4954
  • •设计模式 单例模式2014-04-25阅读5988
  • •设计模式 装饰者模式 带你重回传奇世界2014-04-21阅读7223
  • •设计模式 策略模式 以角色游戏为背景2014-04-19阅读7504
  • •设计模式 外观模式 一键电影模式2014-05-14阅读4326
  • •设计模式 命令模式 之 管理智能家电2014-04-27阅读4644
  • •设计模式 工厂模式 从卖肉夹馍说起2014-04-25阅读7033
  • •设计模式 观察者模式 以微信公众服务为例2014-04-20阅读8399

猜你在找
《C语言/C++学习指南》加密解密篇(安全相关算法)性能测试之tomcat性能调优性能测试之Apache性能调优Spark零基础入门(1):Scala基本数据类型及程序控制“攒课”课题3:安卓编译与开发、Linux内核及驱动
JAVA面试总结okHttp的封装Android 一个改善的okHttp封装库Android 一个改善的okHttp封装库Android OkHttp完全解析
查看评论
12楼 baozhonghaha2016-03-28 10:20发表 [回复]
恭喜,恭喜。。。大神新婚快乐。。
11楼 无泪无悔902016-02-05 15:28发表 [回复]
看到坑货是打dota的,我瞬间觉得我的人生有了目标
10楼 corffen2016-01-30 16:19发表 [回复]
看到坑货二字 我终于忍不住要评论了 嘎嘎嘎
9楼 jacksgun2015-11-12 19:36发表 [回复]
这个例子太逗了。看的我都笑了
8楼 _ontheway_2015-08-17 17:18发表 [回复]
学习了,这模式挺常用的,不过现在才知道这也是一种设计模式
7楼 牛迁迁2015-08-17 09:49发表 [回复]
学习了,理解的不错。
6楼 carbit_tianpan2015-06-14 21:46发表 [回复]
真的很受用
5楼 oilover2015-06-13 22:05发表 [回复]
写的很好!受教了!
4楼 大梦未觉2014-12-25 09:03发表 [回复]
不错,写得挺简洁明了的
3楼 superdcj2014-11-27 11:31发表 [回复]
代码36行少了一个abstract修饰符
public void dealResult(List<Element> results);
2楼 dodoniao2014-09-18 13:37发表 [回复]
可否把爬虫的代码
放到一个公共的地方,大家学习下?
谢谢了
1楼 while-living2014-07-23 17:53发表 [回复]
你英文名叫dota吧。支持支持,但感觉就算知道有这模式,对于要在什么时候用还是不清楚啊,这个只能靠经验了吧。
发表评论
  • 用 户 名:
  • firelightdragon
  • 评论内容:
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

核心技术类目
全部主题 Hadoop AWS 移动游戏 Java Android iOS Swift 智能硬件 Docker OpenStack VPN SparkERP IE10 Eclipse CRM JavaScript 数据库 Ubuntu NFC WAP jQuery BI HTML5 Spring Apache.NET API HTML SDK IIS Fedora XML LBS Unity Splashtop UML components Windows Mobile Rails QEMU KDE Cassandra CloudStack FTC coremail OPhone CouchBase 云计算 iOS6 Rackspace Web App SpringSide Maemo Compuware 大数据 aptech Perl Tornado Ruby Hibernate ThinkPHP HBase Pure Solr Angular Cloud Foundry Redis Scala Django Bootstrap

个人资料

 
鸿洋_
 
  
    • 访问:6861386次
    • 积分:36662
    • 等级: 
    • 排名:第64名
    • 原创:178篇
    • 转载:0篇
    • 译文:6篇
    • 评论:9506条
我的微信公众号

  • 长期为您推荐优秀博文、开源项目、视频等,进入还有好玩的等着你,欢迎扫一扫。

联系方式

新动态


  • QQ群:

    • 429757068
    • 264950424
    • 463081660
    • 请勿重复加群,Thx
文章分类

  • 【Android 5.x】(9)
  • 【Android 精彩案例】(35)
  • 【Android 源码解析】(29)
  • 【Android 自定义控件实战】(29)
  • 【Android 自定义控件之起步】(7)
  • 【Android 快速开发】(12)
  • 【Android 原生开发游戏】(3)
  • 【Java 并发专题】(15)
  • 【android 进阶之路】(62)
  • 【Java 设计模式】(10)
  • 【Android 百度地图】(4)
  • 【html5 css3精彩案例】(14)
  • 【Android github 控件】(10)
  • 【Android 基础】(16)
  • 【Javascript 】(9)
  • 【rabbitMQ 用法】(5)
友情链接

  • 郭霖的博客
  • 夏安明的博客
  • 任玉刚的博客
  • 敬佩的孔老师
  • foruok的订阅号程序视界
  • 泡在网上的日子
我的微博
博客专栏

  HTML5 & CSS3 实战

文章:11篇

阅读:102483

  设计模式融入生活

文章:10篇

阅读:62944

  Android 精彩案例

文章:67篇

阅读:3046828

阅读排行

  • Android Https相关完全解析 当OkHttp遇到Https(1495984)
  • Android Fragment 真正的完全解析(上)(348700)
  • Android RecyclerView 使用完全解析 体验艺术般的控件(195099)
  • Android Fragment 真正的完全解析(下)(144943)
  • Android OkHttp完全解析 是时候来了解OkHttp了(134870)
  • Android 属性动画(Property Animation) 完全解析 (上)

设计模式 模版方法模式 展现程序员的一天相关推荐

  1. 设计模式——模版方法模式详解(论沉迷LOL对学生的危害)

    0. 前言 写在最前面,本人的设计模式类博文,建议先看博文前半部分的理论介绍,再看后半部分的实例分析,最后再返回来复习一遍理论介绍,这时候你就会发现我在重点处标红的用心,对于帮助你理解设计模式有奇效哦 ...

  2. 23种设计模式之工厂方法模式(黑马程序员)

    工厂方法模式 一.概述 二.结构 三.实现 四.总结 在最后 一.概述 定义一个用户创建对象的工厂(接口),让接口的子类决定去实例化哪个对象,依赖其抽象编程.即工厂方法使一个类的实例化延迟到其工厂的子 ...

  3. Java设计模式——模版方法模式

    1.简介 Define the skeleton of an algorithm in an operation,deferring some steps to subclasses.Template ...

  4. 详解设计模式:模版方法模式

    模板方法模式(Template Method Pattern)也被称为模板模式(Template Pattern),是在 GoF 23 种设计模式中定义了的行为型模式. 模板方法模式 定义一个操作中的 ...

  5. 设计模式(九)模版方法模式

    相关文章 设计模式(一)设计六大原则 设计模式(二)单例模式的七种写法 设计模式(三)建造者模式 设计模式(四)简单工厂模式 设计模式(五)观察者模式 设计模式(六)代理模式 设计模式(七)装饰模式 ...

  6. Java设计模式笔记(4)模版方法模式

    模版方法模式:定义一个操作中的算法的框架,而将一些步骤延迟到子类中.使得子类可以不改变一个算法的结构即可重定义该算法的某些步骤. 抽象模版的方法分为两类: 1. 基本方法也叫基本操作,是由子类实现的方 ...

  7. 从设计模式到恋爱宝典,程序员们的福利来了!

    从设计模式到恋爱宝典,程序员们的福利来了! 1.Factory(工厂模式) 2.Builder(建造模式) 3.Factory Method(工厂方法模式) 4.Prototype(原始模型模式) 5 ...

  8. 设计模式——模版方法

    一.首先记住什么模版方法模式(看后面的代码理解): 模版方法模式指在一个方法,里面包含了一个多步骤的算法骨架,其中一个或者多个步骤允许子类延后实现.允许子类在不修改算法的结构的 前提下,对一个或多个步 ...

  9. 模版方法模式/Template Method

    模版方法模式/Template Method 意图/适用场景: 模版方法模式其实是一种应用很广泛的模式,特别是在使用抽象类的时候. 模版方法模式中必然有一个核心的抽象类,不能是接口.声明一些抽象方法, ...

最新文章

  1. Zabbix介绍及安装部署
  2. 提高电脑开机速度的一些基本操作
  3. Confluence 6 为空白空间编辑默认主页
  4. 云计算概况及第一个Azure程序
  5. vb.net如何发送含双引号的字符串。转义双引号
  6. com线程模型实验之三
  7. C#设计模式系列:抽象工厂模式(AbstractFactory)
  8. xp安装python3.4_32位XP系统 Python3.4.4安装scrapy1.6.0
  9. Linux大批量文件rm命令无效
  10. Java程序员技术栈
  11. Preferences DataStore全解析
  12. UVA 12304 (平面几何)
  13. 【C++】模板特化、偏特化
  14. 严昊:25岁接手世界500强企业,公司一年净赚80亿
  15. windows不能确定用户或计算机名称,Windows10开机时提示“用户名或密码不正确”的解决办法...
  16. 【Python 测验 01编程】数值运算
  17. Java中violate关键字详解
  18. vscode win10笔记本 蓝屏_win10 最近突然频繁蓝屏
  19. 区块链需要迈过的几道坎
  20. (00XX系列)摸摸Windows的SEH

热门文章

  1. 概率统计Python计算:样本数据的经验分布函数
  2. ping问题详解(请求超时,无法访问目标主机)
  3. 安装版—安装MySQL
  4. android硬件加速 setLayerType
  5. 安卓人脸检测之FaceDetector
  6. 《计算机网络管理》_Chap2
  7. 京东数科前端岗位面历
  8. polsarpro滤波后没有bmp文件_win10系统右键新建菜单中没有bmp如何解决
  9. powerdesigner 16.5 破解步骤
  10. 英文版VS2010制作中文环境安装包