php设计模式 Template (模板模式)


Posted in PHP onJune 26, 2011

继承关系由于自身的缺陷,被专家们扣上了“罪恶”的帽子。“使用委派关系代替继承关系”,“尽量使用接口实现而不是抽象类继承”等等专家警告,让我们这些菜鸟对继承“另眼相看”。其实,继承还是有很多自身的优点所在。只是被大家滥用的似乎缺点更加明显了。合理的利用继承关系,还是能对你的系统设计起到很好的作用的。而模板方法模式就是其中的一个使用范例。

GOF给模板方法(Template Method)模式定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。这里的算法的结构,可以理解为你根据需求设计出来的业务流程。特定的步骤就是指那些可能在内容上存在变数的环节。

可以看出来,模板方法模式也是为了巧妙解决变化对系统带来的影响而设计的。使用模板方法使系统扩展性增强,最小化了变化对系统的影响。这一点,在下面的举例中可以很明显的看出来。

<?php 
/** 
* 模板模式 
* 
* 定义一个操作中的算法骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构可以定义该算法的某些特定步骤 
* 
*/ 
abstract class TemplateBase 
{ 
public function Method1() 
{ 
echo "abstract Method1<br/>"; 
} public function Method2() 
{ 
echo "abstract Method2<br/>"; 
} 
public function Method3() 
{ 
echo "abstract Method3<br/>"; 
} 
public function doSomeThing() 
{ 
$this->Method1(); 
$this->Method2(); 
$this->Method3(); 
} 
} 
class TemplateObject extends TemplateBase 
{ 
} 
class TemplateObject1 extends TemplateBase 
{ 
public function Method3() 
{ 
echo "TemplateObject1 Method3<br/>"; 
} 
} 
class TemplateObject2 extends TemplateBase 
{ 
public function Method2() 
{ 
echo "TemplateObject2 Method2<br/>"; 
} 
} 
// 实例化 
$objTemplate = new TemplateObject(); 
$objTemplate1 = new TemplateObject1(); 
$objTemplate2 = new TemplateObject2(); 
$objTemplate->doSomeThing(); 
$objTemplate1->doSomeThing(); 
$objTemplate2->doSomeThing();

AbstractClass(抽象类):定义了一到多个的抽象方法,以供具体的子类来实现它们;而且还要实现一个模板方法,来定义一个算法的骨架。该模板方法不仅调用前面的抽象方法,也可以调用其他的操作,只要能完成自身的使命。

ConcreteClass(具体类):实现父类中的抽象方法以完成算法中与特定子类相关的步骤。

根据上面对定义的分析,以及例子的说明,可以看出模板方法适用于以下情况:

一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。其实这可以说是一种好的编码习惯了。
控制子类扩展。模板方法只在特定点调用操作,这样就只允许在这些点进行扩展。比如上面runBare()方法就只在runTest前面适用setUp方法。如果你不愿子类来修改你的模板方法定义的框架,你可以采用两种方式来做:一是在API中不体现出你的模板方法;二、将你的模板方法置为final就可以了。
可以看出,使用模板方法模式可以将代码的公共行为提取出来,达到复用的目的。而且,在模板方法模式中,是由父类的模板方法来控制子类中的具体实现。这样你在实现子类的时候,根本不需要对业务流程有太多的了解。

PHP 相关文章推荐
php checkdate、getdate等日期时间函数操作详解
Mar 11 PHP
PHP中的函数嵌套层数限制分析
Jun 13 PHP
php设计模式 Facade(外观模式)
Jun 26 PHP
PHP strstr 函数判断字符串是否否存在的实例代码
Sep 28 PHP
PHP实现的多彩标签效果代码分享
Aug 21 PHP
ThinkPHP的MVC开发机制实例解析
Aug 23 PHP
PHP中返回引用类型的方法
Apr 03 PHP
编写PHP脚本来实现WordPress中评论分页的功能
Dec 10 PHP
php使用Header函数,PHP_AUTH_PW和PHP_AUTH_USER做用户验证
May 04 PHP
php metaphone()函数及php localeconv() 函数实例解析
May 15 PHP
微信支付开发维权通知实例
Jul 12 PHP
php生成word并下载代码实例
Mar 15 PHP
php设计模式 Proxy (代理模式)
Jun 26 #PHP
php设计模式 Composite (组合模式)
Jun 26 #PHP
php设计模式 State (状态模式)
Jun 26 #PHP
php设计模式 Bridge (桥接模式)
Jun 26 #PHP
php设计模式 Chain Of Responsibility (职责链模式)
Jun 26 #PHP
php设计模式 FlyWeight (享元模式)
Jun 26 #PHP
php设计模式 Mediator (中介者模式)
Jun 26 #PHP
You might like
PHP5中的时间相差8小时的解决办法
2008/03/28 PHP
基于PHP Web开发MVC框架的Smarty使用说明
2013/04/19 PHP
jQuery 学习 几种常用方法
2009/06/11 Javascript
在线一元二次方程计算器实例(方程计算器在线计算)
2013/12/22 Javascript
Javascript前端UI框架Kit使用指南之kitjs事件管理
2014/11/28 Javascript
百度地图API之本地搜索与范围搜索
2015/07/30 Javascript
详解AngularJS实现表单验证
2015/12/10 Javascript
详细谈谈AngularJS的子级作用域问题
2016/09/05 Javascript
微信分享调用jssdk实例
2017/06/08 Javascript
AngularJS中scope的绑定策略实例分析
2017/10/30 Javascript
vue中keep-alive的用法及问题描述
2018/05/15 Javascript
详解js静态检查工具eslint配置文件
2018/11/23 Javascript
用webpack4开发小程序的实现方法
2019/06/04 Javascript
vue实现行列转换的一种方法
2019/08/06 Javascript
vue css 引入asstes中的图片无法显示的四种解决方法
2020/03/16 Javascript
使用typescript快速开发一个cli的实现示例
2020/12/09 Javascript
vue 实现图片懒加载功能
2020/12/31 Vue.js
Vue实现圆环进度条的示例
2021/02/06 Vue.js
[04:15]DOTA2-DPC中国联赛 正赛 Ehome vs Aster 选手采访
2021/03/11 DOTA
python读写ini文件示例(python读写文件)
2014/03/25 Python
python实现的希尔排序算法实例
2015/07/01 Python
彻彻底底地理解Python中的编码问题
2018/10/15 Python
Python从数据库读取大量数据批量写入文件的方法
2018/12/10 Python
Python 虚拟空间的使用代码详解
2019/06/10 Python
Python计算IV值的示例讲解
2020/02/28 Python
详解pandas获取Dataframe元素值的几种方法
2020/06/14 Python
HTML5自定义视频播放器源码
2020/01/06 HTML / CSS
荷兰浴室和卫浴网上商店:Badkamerxxl.nl
2020/10/06 全球购物
Java Servlet API中forward() 与redirect()的区别
2014/04/20 面试题
《假如》教学反思
2014/04/17 职场文书
英语演讲稿3分钟
2014/04/29 职场文书
小学三好学生事迹材料
2014/08/15 职场文书
本科毕业论文导师评语
2014/12/31 职场文书
关于开学的感想
2015/08/10 职场文书
SQL Server中常用截取字符串函数介绍
2022/03/16 SQL Server
Python可视化动图组件ipyvizzu绘制惊艳的可视化动图
2022/04/21 Python