模板方法(Template Method)设计模式中使用了一个类方法templateMethod(), 该方法是抽象类中的一个具体方法, 这个方法的作用是对抽象方法序列排序,具体实现留给具体类来完成.关键在于模板方法模式定义了操作中算法的"骨架",而由具体类来实现.
使用场景:在一系列操作中,我们已经知道了该操作有那些步骤,以及步骤的顺序,只需要用不同的方式去实现这些步骤,这是我们可以使用模版方法抽象一个类出来,抽象类里面有具体的实现方法以及对这些实现方法的操作;
eg:
要建立带图题的图像. 这个算法相当简单, 就是显示图像, 然后的图像下面显示文本.不同的图片可能有不同的方式来展示
abstract class Template
{
protected $picture;
protected $title;
//实现方法的过程
public function display($pictureNow, $titleNow)
{
$this->picture = $pictureNow;
$this->title = $titleNow;
$this->addPicture($this->picture);
$this->addTitle($this->title);
}
//具体需要实现的方法
abstract protected function addPicture($picture);
abstract protected function addTitle($title);
}
//根据不同的需求实现需要实现的方法
class Concrete extends Template
{
protected function addPicture($picture)
{
$this->picture = 'picture/' . $picture;
echo "图像路径为:" . $this->picture . '<br/>';
}
protected function addTitle($title)
{
$this->title = $title;
echo "<em>标题: </em>" . $this->title . "<br/>";
}
}
class Client
{
public function __construct()
{
//这里我们根据不同的需求调用不同的实现方法;
$title = "chenqionghe is a handsome boy";
$concrete = new Concrete();
$concrete->display('chenqionghe.png', $title);
}
}
$worker = new Client();
再比如银行流水的上传我们有很多种银行,不同的银行的流水模版是不一样的,所以处理方式是一样的,但不同的银行模版的处理过程一样,步骤:检验银行流水的模版-》流水上传到腾讯云-》取出流水模版的数据-》对取出的数据进行分类以及保存;对于上面的需求我们可以先建立一个固定的模版,然后不同的银行流水有自己的处理流水的类,客户根据不同的流水调用不同的类;
上面我们可以看到模版方法里面的所有步骤是固定的,这样就有个问题,我们假如有的模版流程有一点变化,这时候可能就用不了模版方法了,针对这种情况我们可以利用钩子来解决,可以利用钩子来决定是否需要某一个步骤。
abstract
class
IHook
{
protected
$hook
;
protected
$fullCost
;
public
function
templateMethod(
$fullCost
,
$hook
)
{
$this
->fullCost =
$fullCost
;
$this
->hook =
$hook
;//这里的钩子可以给后面使用,判断是否需要做某一个操作;
$this
->addGoods();
$this
->addShippingHook();
$this
->displayCost();
}
protected
abstract
function
addGoods();
protected
abstract
function
addShippingHook();
protected
abstract
function
displayCost();
}
class
Concrete
extends
IHook
{
protected
function
addGoods()
{
$this
->fullCost =
$this
->fullCost * 0.8;
}
protected
function
addShippingHook()
{
if
(!
$this
->hook)
{
$this
->fullCost += 12.95;
}
}
protected
function
displayCost()
{
echo
"您需要支付: "
.
$this
->fullCost .
'元<br />'
;
}
}
class
Client
{
private
$totalCost
;
private
$hook
;
public
function
__construct(
$goodsTotal
)
{
$this
->totalCost =
$goodsTotal
;
$this
->hook =
$this
->totalCost >= 200;
$concrete
=
new
Concrete();
$concrete
->templateMethod(
$this
->totalCost,
$this
->hook);
}
}
$worker
=
new
Client(100);
$worker
=
new
Client(200);