什么是模板方法模式
- 这个方法的作用是对抽象方法序列排序,具体实现留给具体类来完成
- 关键在于模板方法模式定义了操作中算法的“骨架”,而由具体类来实现
何时使用模板方法
- 如果已经明确算法中的一些步骤,不过这些步骤可以采用多种不同的方法实现
- 还有一种用法,可能需要把子类共同的行为放在一个类中,以避免代码重复。
- 还可以使用模板方法模式控制子类扩展。这里涉及到一个”钩子“ 操作
好菜坞原则
- 这个原则是指父类调用子类的操作,而不是子类不调用父类的操作
- 例:
function __autoload($class_name) {
include $class_name.'.php';
}
class client {
function __construct() {
$mo = new TmFac();
$mo->templateMethod();
}
}
$worker = new Client();
abstract Tmab {
protected $pix;
protected $cap;
public function templateMethod() {
$this->addPix();
$this->addCaption();
}
protected abstract function addPix();
protected abstract function addCaption();
}
class TmFac extends TmAb {
protected function addPix() {
$this->pix = new GRaphicFactory();
echo $this->pix->doFactory();
}
protected function addCaption() {
$this->cap = new TextFactory();
echo $this->cap->doFactory();
}
}
模板方法设计模式中的钩子
- 例如,假设有一个模板方法,可以累加一个订单的总费用,另外加上税和运费,然后显示交易总金额。不过,如果买家购买需要送货的商品超过200美元,可以免运费
- 利用钩子可以将一个方法作为模板方法的一部分,不过不一定会用到这个方法(可以处理例外情况)
- 子类可以为算法增加一个可选元素
建立钩子
abstract class IHook {
protected $purchased;
protected $hookSpecial;
protected $shippingHook;
protected $fullCost;
public function templateMethod($total, $special) {
$this->purchased = $total;
$this->hookSpcial = $spcial;
$this->addTax();
$this->addShippingHook();
$this->displayCost();
}
protected abstract function addTax();
protected abstract function addShippingHook();
protected abstract function displayCost();
}
class ZambeziCalc extends IHook {
protect function addTax() {
$this->fullCost = $this->purchased + ($this->purchased * 0.07);
}
protect function addShippingHook() {
if(!$this->hookSpecial) {
$this->FullCost += 12.95;
}
}
protect function displayCost() {
echo "Your full cost is $this->fullCost";
}
}
$this->special = ($this->bugTotal >= 200);
function __autoload($class_name) {
include $class_name.'.php';
}
class Client {
private $buyTotal;
private $gpsNow;
private $mapNow;
private $boatNow;
private $special;
private $zamCalc;
function __construct() {
$this->setHtml();
$this->setCost();
$this->zamCalc = new ZambeziCalc();
$this->zamCalc->templateMethod($this->bugTotal, $this->special);
}
private function setHTML() {
$this->gpsNow = $_POST['gps'];
$this->mapNow = $_POST['map'];
$this->boatNow = $_POST['boat'];
}
private function setCost() {
$this->buyTotal = $this->gpsNow;
foreach($this->mapNow as $value) {
$this->buyTotal += $value;
}
$this->special = ($this->buyTotal >= 200);
$this->buyTotal += $this->boatNow;
}
}
$worker = new Client();