php-模板方式模式实现
概述
模板方法(Template Method)设计模式中使用了一个类方法templateMethod(), 该方法是抽象类中的一个具体方法, 这个方法的作用是对抽象方法序列排序,具体实现留给具体类来完成.关键在于模板方法模式定义了操作中算法的"骨架",而由具体类来实现.
摩托车有地方造了,本篇就不造了。本篇我们以销售摩托车为例,现有A,B两种类型门店类型。针对A和B两种门店分别制定了激励政策。A门店销售额满100万奖励15%,B门店销售额满100万奖励10%。以此来激励门店业务人员。实现该需求需要建立狗子(hook)基于模板方法模式。
模式结构
以本文实例代码为参考
- MotorSaleTemplate-摩托销售模板类
- MotorProxyA -销售代理A
- MotorProxyB-销售代理B
UML图例
代码实例
<?php
/**
* +----------------------------------------------------------------------+
* php23种设计模式实现-模板方法模式
* Author:微信公众号:yuantanphp
* 获取更多资源,技术答疑,项目合作请关注微信公众号:yuantanphp
* +----------------------------------------------------------------------+
*/
/**摩托销售模板类 */
abstract class MotorSaleTemplate{
protected $sale_volu; //销售额
protected $hook; //狗子
protected $commission; //提成
protected $target_sale_volu; //目标销售额
//模板方法
function template($sale_volu)
{
$this->sale_volu = $sale_volu;
$this->hook = $sale_volu >= $this->target_sale_volu;
$this->setBonus();
// $this->customer = $customer;
}
//计算奖金
abstract function setBonus();
abstract function getBonus();
}
//销售代理A
class MotorProxyA extends MotorSaleTemplate{
public function setBonus()
{
$this->commission = 0;
$this->target_sale_volu = 1000000;
if($this->hook){
$this->commission = $this->sale_volu * 0.15;
}
}
public function getBonus()
{
return $this->commission;
}
}
//销售代理B
class MotorProxyB extends MotorSaleTemplate{
public function setBonus()
{
$this->commission = 0;
$this->target_sale_volu = 1000000;
if($this->hook){
$this->commission = $this->sale_volu * 0.10;
}
}
public function getBonus()
{
return $this->commission;
}
}
$saleVolu = 150000;
$motorProxyA = new MotorProxyA();
$motorProxyA->template($saleVolu);
var_dump($motorProxyA->getBonus());
echo "<br>";
$saleVolu = 150000;
$motorProxyB = new MotorProxyB();
$motorProxyB->template($saleVolu);
var_dump($motorProxyB->getBonus());
模式分析
模板方法模式是通过把不变行为搬移到超类,去除子类中的重复代码来体现它的优势,我们通过模板方法把这些行为搬移到单一的地方,这样就帮助子类摆脱重复的不变行为的纠缠。
优缺点
模板方法优点
符合“开闭原则“、”里氏替换原则”
- 封装不变部分,扩展可变部分。
- 统一公共部分代码,便于维护。
- 行为由父类控制,子类实现
模板方法缺点
1、类数量的增加,间接地增加了系统实现的复杂度。
2、继承关系自身缺点,如果父类添加新的抽象方法,所有子类都要改一遍。
适用环境
如果已经明确算法中的一些步骤, 不过这些步骤可以采用多种不同的方法实现, 就可以使用模板方法调试.如果算法中的步骤不变, 可以把这些步骤留给子类具体实现.在这种情况下, 可以使用模板方法设计模式来组织抽象类中的基本操作(函数/方法).然后由子类来实现应用所需的这些操作.
还有一种用法稍微复杂一些, 可能需要把子类共同的行为放在一个类中, 以避免代码重复.
如果使用多个类来解决同一个大型问题, 可能很快就会出现重复代码.
还有一点,可以使用模板方法模式控制子类扩展,也就是所谓的"钩子".
关注微信公众号(yuantanphp) | |
---|---|
回复关键字 设计模式 可获取以下材料 《设计模式:可复用面向对象软件的基础》pdf版. php设计模式23种实例实现php源码 | ![]() |