PHP设计模式之模板方法模式定义与用法详解

本文实例讲述了PHP设计模式之模板方法模式定义与用法。分享给大家供大家参考,具体如下:

什么是模板方法模式

模板方法(Template Method)

设计模式中使用了一个类方法templateMethod(),该方法是抽象类中的一个具体方法,这个方法的作用是对抽象方法序列排序,具体实现留给具体类来完成.关键在于模板方法模式定义了操作中算法的"骨架",而由具体类来实现.

什么时候使用模板方法

如果已经明确算法中的一些步骤,不过这些步骤可以采用多种不同的方法实现,就可以使用模板方法调试.如果算法中的步骤不变,可以把这些步骤留给子类具体实现.在这种情况下,可以使用模板方法设计模式来组织抽象类中的基本操作(函数/方法).然后由子类来实现应用所需的这些操作.

还有一种用法稍微复杂一些,可能需要把子类共同的行为放在一个类中,以避免代码重复.

如果使用多个类来解决同一个大型问题,可能很快就会出现重复代码.

还有一点,可以使用模板方法模式控制子类扩展,也就是所谓的"钩子".

示例

在PHP编程中,可能经常会遇到一个问题: 要建立带图题的图像. 这个算法相当简单,就是显示图像,然后的图像下面显示文本.

由于模板设计中只涉及两个参与者,所以这是最容易理解的模式之一,同时也非常有用. 抽象建立templateMethod(),并由具体类实现这个方法.

抽象类

抽象类是这里的关键,因为它同时包含具体和抽象方法. 模板方法往往是具体方法,其操作是抽象的

两个抽象方法分别是addPicture和addTitile,这两个操作都包含一个参数,分别表示图像的URL信息和图像标题.

Template.php

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

picture = 'picture/' . $picture; echo "图像路径为:" . $this->picture . '
'; } protected function addTitle($title) { $this->title = $title; echo "标题: " . $this->title . "
"; } }

客户

Client.php

display('chenqionghe.png',$title); } } $worker = new Client();

$concrete变量实例化了Concrete,但是它调用了display模板方法,这是从父类继承的具体操作,父类通过display()调用子类的操作.

运行后输出

图像路径为:picture/chenqionghe.png 标题: chenqionghe is a handsome boy

可以看到,客户只需要提供图像地址和标题

模板方法设计模式中的钩子

有时模板方法函数可能有一个你不想要的步骤,某些特定情况下你可能不希望执行这个步骤,这时候就可以用到模板方法的钩子.

在模板方法设计模式中,利用钩子可以将一个方法作为模板的一部分,不过不一定会用到这个方法,换句话说,它是方法的一部分,不过它包含一个钩子,可以处理例外情况. 子类可以为算法增加一个可选元素,这样一来,尽管仍按模板方法建立的顺序执行,但有可能并不完成模板方法期望的动作. 对于这种可选的情况,钩子就是解决这个问题最理想的工具.

示例

去网购商品,登场8折,如果总商品费用超过200元,就免去12.95元钱运费.

建立钩子

在模板方法中建立钩子方法很有意思,尽管子类可以改变钩子的行为,但仍然要遵循模板中定义的顺序

IHook.php

fullCost = $fullCost; $this->hook = $hook; $this->addGoods(); $this->addShippingHook(); $this->displayCost(); } protected abstract function addGoods(); protected abstract function addShippingHook(); protected abstract function displayCost(); }

这里有3个抽象方法: addGoods(),addShippingHook(),displayCost(),抽象类IHook实现的templateMethod()中确定了它们的顺序. 在这里,钩子方法放在中间,实际上模板方法指定的顺序中,钩子可以放在任意位置. 模板方法需要两个参数,一个是总花费,另外还需要一个变量用来确定顾客是否免收运费.

实现钩子

一旦抽象类中建立了这些抽象方法,并指定了它们执行的顺序,子类将实现所有这3个方法:

Concrete.php

fullCost = $this->fullCost * 0.8; } protected function addShippingHook() { if(!$this->hook) { $this->fullCost += 12.95; } } protected function displayCost() { echo "您需要支付: " . $this->fullCost . '元
'; } }

addGoods和displayCost都是标准方法,只有一个实现.,不过,addShippingHook的实现有所不同,其中有一个条件来确定是否增加运费. 这就是钩子.

客户Client

Client.php

totalCost = $goodsTotal; $this->hook = $this->totalCost >= 200; $concrete = new Concrete(); $concrete->templateMethod($this->totalCost,$this->hook); } } $worker = new Client(100); $worker = new Client(200);

该Client演示了分别购买100块钱和200块钱的商品最后的费用,运行结果如下

您需要支付: 92.95元 您需要支付: 160元

更多关于PHP相关内容感兴趣的读者可查看本站专题:《》、《》、《》、《》、《》及《

希望本文所述对大家PHP程序设计有所帮助。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


如何选择合适的 C++ Web 开发框架?
利用 C++ 框架构建高并发 Web 应用的策略
用 C++ 框架开发跨平台图形应用程序
golang框架中安全编码实践的最佳指南是什么?
golang框架与其他语言框架在设计理念上的区别有哪些?
C++ 图形框架与其他语言框架的比较
C++ 框架与其他 Web 开发框架的对比分析
使用 C++ 框架构建大型项目最佳实践
C++ 框架如何提高大型项目开发效率
C++ 框架中依赖注入的持续集成与部署工具
如何与社区协作和贡献到自定义 Golang 框架?
C++ 框架在大型项目中如何实现模块化开发
使用 C++ 框架开发跨平台 Web 应用
C++ 框架在大型项目中的优缺点
golang框架在性能上的优势体现在哪些方面?
C++ 框架在嵌入式系统内存优化中的优势
golang框架在人工智能与机器学习中的作用
如何扩展 Golang 框架以支持特定功能?
如何利用 Go Modules 和依赖项管理来自定义 Golang 框架?
Golang 框架中的性能优化技巧