【案例:确定玩具的购买价格 】
黑枣玩具公司的产品五花八门,不同的产品价格计算方式也不一样。所以对价格计算系统的要求非常高。价格因素主要包括以下几点。
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
******************转载请注明来源 ***************