這次帶給大家PHP模板方法模式使用詳解,PHP模板方法模式使用的注意事項有哪些,下面就是實戰案例,一起來看一下。
什麼是範本方法模式
#範本方法(Template Method)設計模式中使用了一個類別方法templateMethod(), 該方法是抽象類別中的一個具體方法, 這個方法的作用是對抽象方法序列排序,具體實現留給具體類別來完成.關鍵在於模板方法模式定義了操作中演算法的"骨架",而由具體類別來實現.
什麼時候使用模板方法
如果已經明確演算法中的一些步驟,不過這些步驟可以採用多種不同的方法實現, 就可以使用模板方法調試.如果算法中的步驟不變, 可以把這些步驟留給子類具體實現.在這種情況下, 可以使用模板方法設計模式來組織抽象類別中的基本操作(函數/方法).然後由子類別來實現應用所需的這些操作.
#還有一種用法稍微複雜一些, 可能需要把子類別共同的行為放在一個類別中, 以避免程式碼重複.
如果使用多個類別來解決同一個大型問題, 可能很快就會出現重複程式碼.
#還有一點,可以使用模板方法模式控制子類別擴展,也就是所謂的"鉤子".
範例
在PHP程式設計中,可能經常會遇到一個問題: 要建立帶圖題的圖像. 這個演算法相當簡單, 就是顯示圖像, 然後的圖像下面顯示文本.
由於模板設計中只涉及兩個參與者, 所以這是最容易理解的模式之一, 同時也非常有用. 抽象建立templateMethod()
,並由具體類別實作這個方法.
抽象類別
##抽象類別是這裡的關鍵, 因為它同時包含具體和抽象方法. 模板方法往往是具體方法, 其操作是抽象的兩個抽象方法分別是addPicture和addTitile,這兩個操作都包含一個參數, 分別表示圖像的URL資訊與圖片標題.Template.php
<?php 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); }
特定類別
##Concrete.php<?php
include_once('Template.php');
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 />";
}
}
Client.php
<?php
function autoload($class_name)
{
include $class_name . '.php';
}
class Client
{
public function construct()
{
$title = "chenqionghe is a handsome boy";
$concrete = new Concrete();
$concrete->display('chenqionghe.png', $title);
}
}
$worker = new Client();
$concrete變數實例化了Concrete, 但是它呼叫了display模板方法, 這是從父類別繼承的具體操作, 父類別透過
呼叫子類別的操作.#運行後輸出
標題: chenqionghe is a handsome boy可以看到,客戶只需要提供圖片位址和標題
#模板方法設計模式中的鉤子有時模板方法函數可能有一個你不想要的步驟, 某些特定情況下你可能不希望執行這個步驟, 這時候就可以用到模板方法的鉤子.
在模板方法設計模式中, 利用鉤子可以將一個方法作為模板的一部分,不過不一定會用到這個方法, 換句話說, 它是方法的一部分,不過它包含一個鉤子, 可以處理例外情況. 子類可以為算法增加一個可選元素, 這樣一來, 儘管仍按模板方法建立的順序執行, 但有可能並不完成模板方法期望的動作. 對於這種可選的情況, 鉤子就是解決這個問題最理想的工具.
範例#去網購商品, 登場8折, 如果總商品費用超過200元, 就免去12.95元錢運費.
建立鉤子在模板方法中建立鉤子方法很有意思, 儘管子類別可以改變鉤子的行為, 但仍然要遵循模板中定義的順序
IHook.php# 这里有3个抽象方法: 实现钩子 一旦抽象类中建立了这些抽象方法, 并指定了它们执行的顺序, 子类将实现所有这3个方法: Concrete.php addGoods和displayCost都是标准方法, 只有一个实现., 不过, addShippingHook的实现有所不同, 其中有一个条件来确定是否增加运费. 这就是钩子. 客户Client Client.php 该Client演示了分别购买100块钱和200块钱的商品最后的费用,运行结果如下 您需要支付: 92.95元 相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章! 推荐阅读:<?php
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();
}
addGoods()
, addShippingHook()
,displayCost()
, 抽象类IHook实现的templateMethod()
中确定了它们的顺序. 在这里, 钩子方法放在中间, 实际上模板方法指定的顺序中, 钩子可以放在任意位置. 模板方法需要两个参数, 一个是总花费, 另外还需要一个变量用来确定顾客是否免收运费.<?php
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 />';
}
}
<?php
function autoload($class_name)
{
include $class_name . '.php';
}
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);
您需要支付: 160元
以上是PHP模板方法模式使用詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!