Php設計模式之【模板方法模式Template Method Pattern 】

【案例:確定玩具的購買價格 】

黑棗玩具公司的產品五花八門,不同的產品價格計算方式也不一樣。所以對價格計算系統的要求非常高。價格因素主要包括以下幾點。

1. 不同的產品有不同的增值稅ValueAddTax關稅TariffTax

2. 還有一些玩具需要交其它的稅類。如果是塑料玩具,還可能要繳納環境污染稅,其它稅還有印花稅、資源等,統稱爲OtherTax

這些費用最終會加入最後的購買價格。

【分析OOA 】

每一種產品的價格都要加上額外的交稅花費,計算最後價格的算法可以說是固定不變的,只是不同的玩具對不同的稅種有不同的稅率。

模板方法就是關於怎麼樣將若干個方法集成到一個方法中,以便形成一個解決問題的算法骨架,它的關鍵在於,在一個抽象類中定義一個算法骨架,即將若干個方法集成到一個方法中,並稱該方法爲一個模板方法,或直接就叫模板。模板方法所調用的其他方法通常稱爲抽象的方法,這些抽象的方法相當於算法骨架中的各個步驟,這些步驟的實現可以由子類去完成。(實際處理交給子類區處理)

【設計OOD 】

<UML>


<說明>

1. ToyTemplate爲抽象摸板角色.

   定義並實現了一個摸板方法setPriceAdjustments,被聲明爲final,子類無法覆蓋該方法

   定義了一個或多個抽象操作,如getValueAddTax、getTariffTax以便讓子類實現。

2. WoodDogToy(木頭玩具狗)、PlasticDogToy(塑料玩具狗)爲具體摸板角色,實現父類ToyTemplate所定義的一個或多個抽象方法.

【編程 OOP 】

<代碼>

abstract class ToyTemplate
{
    public $price = 0;

    public final function setPriceAdjustments()
    {
        $this->price += $this->getValueAddTax();
        $this->price += $this->getTariffTax();
        $this->price += $this->getOtherTax();
    }

    protected function getOtherTax()
    {
        return 0;
    }

    abstract protected function getValueAddTax();

    abstract protected function getTariffTax();
}

//木頭玩具狗,需要交增值稅ValueAddTax、關稅TariffTax
class WoodDogToy extends ToyTemplate
{
    public $price = 100;

    protected function getTariffTax()
    {
        return round($this->price * 0.40);
    }

    protected function getValueAddTax()
    {
        return round($this->price * 0.12);
    }
}

//塑料玩具狗,需要交增值稅ValueAddTax、關稅TariffTax及環境污染稅
class PlasticDogToy extends ToyTemplate
{
    public $price = 100;

    protected function getTariffTax()
    {
        return round($this->price * 0.40);
    }

    protected function getValueAddTax()
    {
        return round($this->price * 0.12);
    }

    protected function getOtherTax()
    {
        return round($this->price * 0.5);
    }
}


【測試用例Test Case:

<代碼>

class testDriver
{
    public function run()
    {
        $wooddog = new WoodDogToy();
        $wooddog->setPriceAdjustments();
        echo "Wood Dog Toy Price:" . $wooddog->price . "\n";
        $plasticdog = new PlasticDogToy();
        $plasticdog->setPriceAdjustments();
        echo "Plasti Dog Toy Price:" . $plasticdog->price . "\n";
    }
}

$test = new testDriver();
$test->run();

【輸出 】


小結:

摸板方法(Template Method)模式是一種非常簡單而又經常使用的設計模式.先創建一個父類,把其中的一個或多個方法留給子類去實現,這實際上就是在使用摸板模式.所謂的摸板模式可以這樣來理解:"在一個類中定義一個算法,但將此算法的某些細節留到子類中去實現.換句話說,基類是一個抽象類,那麼你就是在使用一種簡單形式的摸板模式." 

抽象模板角色裏提供完整的方法,它完成了所有派生類都要用到的一些基本功能. 

抽象模板角色裏面提供子類要繼承或必須實現的方法。其代碼實現方式可爲

1,抽象模板角色裏只提供空方法,把功能全部留給派生類去實現. 

2,抽象模板角色裏只包含某些操作的默認實現,派生類裏可以重新定義這些方法的實現. 

3, 抽象模板角色裏模板方法,他是一個調用抽象方法,鉤子方法以及具體方法的各種組合 

【常用情境】

1,設計者需要給出一個算法的固定步驟,並將某些步驟的具體實現留給子類來實現。

2,需要對代碼進行重構,將各個子類公共行爲提取出來集中到一個共同的父類中以避免代碼重負。  

【模板方法優點】

1、封裝不變部分(算法框架),擴展可變部分

2、提取公共部分代碼,便於維護

3、行爲由父類控制,子類實現,使得算法相對穩定,易於擴展

【模板方法缺點 】

違背了正常的設計習慣,一般抽象類都負責聲明最抽象,最一般的失誤屬性和方法,實現由其子類實
但模板方法則相反,其實現雖由子類實現,但子類的執行結果卻影響了父類,這很容易帶來代碼閱讀難度 


********************************************

* 作者:uuleaf 

* 標題:Php設計模式之【模板方法模式Template Method Pattern 】

* 參考:

*《Head First設計模式》Eric Freeman等著

*《PHP設計模式》Aaron Saray等著,樑志敏等譯(PS:翻譯的是狗屁水平)

*  模板方法模式 http://www.cnblogs.com/tjcjxy/archive/2010/12/09/1901447.html

*   解讀設計模式----模板方法模式(Template Method) http://tech.ddvip.com/2008-12/122906852999552.html

******************轉載請註明來源 ***************


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章