PHP设计模式之模板方法(Template Method)详解
模板方法(Template Method)是一种行为型设计模式,它定义了一个操作中的算法骨架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
模板方法模式概述
在面向对象设计中,继承虽然强大但若滥用会导致系统脆弱。专家常建议“使用委派关系代替继承关系”,但在合理控制下,继承依然是实现代码复用的有力工具。模板方法模式正是利用继承特性来解决系统中变化的一种经典范例。
GOF(GoF)对该模式的定义为:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。这里的“算法结构”可理解为根据需求设计的业务流程骨架,“特定步骤”则是那些在内容上存在变数、需要由具体场景决定的环节。
使用模板方法模式能够显著增强系统的扩展性,最小化变化对系统整体架构的影响。
核心角色与结构
模板方法模式主要包含两个核心角色:
- AbstractClass(抽象类):定义了一个或多个抽象方法,以供具体的子类来实现;同时必须实现一个模板方法,用来定义算法的骨架。该模板方法不仅调用前面的抽象方法,也可以调用其他的操作,只要能完成自身的使命。
- ConcreteClass(具体类):实现父类中的抽象方法,以完成算法中与特定子类相关的步骤。
第1步:定义抽象基类与算法骨架
首先,创建一个抽象类,在其中定义算法的执行流程(模板方法),以及需要子类实现的抽象方法或钩子方法。
<?php
/**
* 模板模式 - 抽象基类
*
* 定义一个操作中的算法骨架,而将一些步骤延迟到子类中,
* 使得子类可以不改变一个算法的结构可以定义该算法的某些特定步骤
*/
abstract class TemplateBase {
// 具体方法:在基类中已实现,子类可复用或重写
public function Method1() {
echo "abstract Method1<br/>";
}
public function Method2() {
echo "abstract Method2<br/>";
}
// 抽象方法:强制子类必须实现
abstract public function Method3();
/**
* 模板方法:定义算法骨架
* final 关键字防止子类篡改流程顺序
*/
public function doSomeThing() {
$this->Method1();
$this->Method2();
$this->Method3();
}
}
第2步:创建具体子类并重写特定步骤
不同的业务场景继承自同一个抽象类,但根据需要重写特定的方法(如 Method3),从而在不改变整体流程的前提下改变局部行为。
// 默认实现(若不需要重写任何方法,可直接调用基类逻辑)
class TemplateObject extends TemplateBase {
// 如果未重写 Method3,需确保基类中有具体实现或使用默认值策略
// 在此示例中,为演示方便,假设基类也有具体实现或此为特殊情况
}
// 子类1:重写 Method3
class TemplateObject1 extends TemplateBase {
public function Method3() {
echo "TemplateObject1 Method3<br/>";
}
}
// 子类2:如果需要,也可以重写其他方法
// 注意:本例中 doSomeThing 调用了 Method3,故子类需实现该方法
第3步:实例化并执行模板方法
客户端代码无需关心内部具体实现了哪些步骤,只需调用父类的 doSomeThing() 方法,程序会自动按照定义的顺序执行各步骤。
// 实例化对象
$objTemplate = new TemplateObject();
$objTemplate1 = new TemplateObject1();
// 如果有另一个变体
// $objTemplate2 = new TemplateObject2();
// 执行相同的方法,但产生不同结果
$objTemplate->doSomeThing();
$objTemplate1->doSomeThing();
// $objTemplate2->doSomeThing();
适用场景与优势
根据上述分析与实践,模板方法模式适用于以下情况:
- 一次性实现算法不变部分:将算法中固定不变的步骤放在父类中,将可变的步骤留给子类实现。
- 提取公共行为以避免代码重复:当多个子类拥有相同的算法流程时,通过父类提取公共代码,符合DRY(Don't Repeat Yourself)原则。
- 控制子类扩展:模板方法只在特定点调用操作,限制子类只能在预定义的点进行扩展。如果你希望严格锁定算法框架,禁止子类修改流程,可以采取两种措施:一是在API中隐藏模板方法的实现细节;二、将模板方法声明为
final。
可以看出,使用模板方法模式可以将代码的公共行为提取出来达到复用目的。更重要的是,流程由父类严格控制,子类实现者无需了解整体业务流程的全貌,只需关注自己负责的具体步骤,降低了耦合度。
以上就是PHP模板方法模式设计与应用的详细内容,更多关于PHP设计模式优化与面向对象编程的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













