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

2015-01-24信息快讯网

定义一个操作中的算法骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构可以定义该算法的某些特定步骤

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

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就可以了。
可以看出,使用模板方法模式可以将代码的公共行为提取出来,达到复用的目的。而且,在模板方法模式中,是由父类的模板方法来控制子类中的具体实现。这样你在实现子类的时候,根本不需要对业务流程有太多的了解。
thinkphp3.0 模板中函数的使用
thinkPHP的Html模板标签使用方法
PHP类与对象中的private访问控制的疑问
php类中private属性继承问题分析
PHP5下$_SERVER变量不再受magic_quotes_gpc保护的弥补方法
php daddslashes()和 saddslashes()有哪些区别分析
PHP daddslashes 使用方法介绍
php模板函数 正则实现代码
记录PHP错误日志 display_errors与log_errors的区别
PHP 正则表达式之正则处理函数小结(preg_match,preg_match_all,preg_replace,preg_split)
Thinkphp模板中使用自定义函数的方法
php获取ip的三个属性区别介绍(HTTP_X_FORWARDED_FOR,HTTP_VIA,REMOTE_ADDR)
php中使用exec,system等函数调用系统命令的方法(不建议使用,可导致安全问题)
Erlang的运算符(比较运算符,数值运算符,移位运算符,逻辑运算符)
PHP原生模板引擎 最简单的模板引擎
Php Ctemplate引擎开发相关内容
php设计模式 Command(命令模式)
php设计模式 Proxy (代理模式)
php设计模式 Composite (组合模式)
php设计模式 State (状态模式)
PHP5中新增stdClass 内部保留类
PHP中遍历stdclass object的实现代码
使ecshop模板中可引用常量的实现方法
php自动获取字符串编码函数mb_detect_encoding
PHP数组的交集array_intersect(),array_intersect_assoc(),array_inter_key()函数的小问题
php file_put_contents()功能函数(集成了fopen、fwrite、fclose)
Views rows style模板重写代码
php调用mysql数据 dbclass类
PHP的substr_replace将指定两位置之间的字符替换为*号
在smarty模板中使用PHP函数的方法
flash用php连接数据库的代码
PHP中MVC模式的模板引擎开发经验分享
php模板中出现空行解决方法
Blitz templates 最快的PHP模板引擎
©2014-2024 dbsqp.com