前段时间实在是太忙,本来是准备每天都写一篇博客的。结果也没有坚持下来。今天就接着说说模版模式。
定义:定义一个操作中算法的骨架,而将这些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤.
可能光看定义确实不容易理解,其实挺简单。就是需要定义一个父类,父类必须定义为抽象类,封装了一些通用的实现逻辑,另外父类需要提供一些抽象的方法。而这些抽象方法则在子类中去做具体的实现。
举一个场景: 加入我们现在有一个类专门用于操作数据库。在一行记录被插入数据之前或者插入之后我们可能需要一些额外的逻辑。那么这时候我们就可以采用模板模式。
先看看模版模式的UML类图
首先我们定义了一个AbstractObject的父类,该父类有一个save方法,和两个抽象的方法_beforeSave和_afterSave。另外有两个子类继承AbstractObject类分别去对_beforeSave和_afterSave去做具体的实现。
<?php
abstract class AbstractObject{
protected abstract function _beforeSave();
protected abstract function _afterSave();
public function save(){
$this->_beforeSave();
//这里是save方法公共的逻辑
echo "这里是save方法公共的逻辑"."<br/>";
$this->_afterSave();
}
}
class File extends AbstractObject{
protected function _beforeSave(){
// 这里保存file对象之前需要做的事情
//比如说生成缩略图之类的
echo "我在save file 之前执行了"."<br/>";
}
protected function _afterSave(){
// 这里保存file对象之后需要做的事情
//比如级联更新相关的信息
echo "我在save file之后执行了"."<br/>";
}
}
class Task extends AbstractObject{
protected function _beforeSave(){
// 这里保存task对象之前需要做的事情
echo "我在save task之前执行了"."<br/>";
}
protected function _afterSave(){
// 这里保存task对象之后需要做的事情
//比如级联更新相关的信息
echo "我在save task之后执行了"."<br/>";
}
}
客户端调用
//客户端调用
$file = new File();
$file->save();
$file = new Task();
$file->save();
输出:
我在save file 之前执行了
这里是save方法公共的逻辑
我在save file之后执行了
我在save task之前执行了
这里是save方法公共的逻辑
我在save task之后执行了
在上面的代码中,AbstractObject类定义了一个算法的骨架,他提供了save方法的公共实现,并且声明了两个方法_beforeSave()和_afterSave()这两个方法就留给具体的子类去实现。这样我们就可以根据具体的需要去实现save方法具体步骤了。
其实模版方法使用还是挺广泛的,在之前我做一个notify的功能的时候也用到了,不同的notify需要不同的参数,我把设置参数的这个方法声明为抽象方法,然后在具体的子类中去设置参数。而父类就将notify的公共实现完成就好。