php设计模式(3) 模板模式
概述
模板模式属于 类行为 型模式。
在面向对象开发过程中,通常我们会遇到这样一个问题:我们知道一个算法所需的关键步骤,并确定了这些步骤的执行顺序。但是某些步骤的具体实现是位置的,或者说某些步骤的具体实现和环境相关
例子:银行业务办理流程
在银行办理业务时,一般都包含几个基本固定步骤:
取号排队->办理具体业务->对银行工作人员进行评分。
取号取号排队和对银行工作人员进行评分业务逻辑是一样的。但是办理具体业务是个不相同的,具体业务可能取款、存款或者转账。
问题
如何保证架构逻辑的正常执行,而不被子类破坏?
解决
模板模式:定义一个操作中的算法骨架,将一些步骤延迟到子类中。模板方法可以不改变一个算法的结构即可重新定义该算法的某些特定步骤
适用性
- 一次性实现一个算法的不变部分,并将可变的行为留给子类来具体实现。
- 各子类中公告的行为应该被提取出来并集中到一个公共父类中,以避免代码重复。(首先识别现有的代码中的不同之处,并且将不同之处分离为新的操作。最后用一个调用这些新操作的模板方法来替代这些不同的代码。)
- 控制子类拓展。(模板方法只在特定点调用 hook 操作,这样就只允许在这些点进行拓展)
模板成员
抽象类 : 定义算法的骨架(抽象方法/具体方法)
具体子类 : 实现抽象类中特定的方法和相关步骤
优点
- 模板模式在一个类中 形式化 的定义算法,具体实现则由子类来完成。
- 模板模式是一种代码复用的基本技术,它们在类库中尤为重要,它们可以提取类中的公告行为。
- 模板模式是一种反向的控制结构(通过其父类调用子类操作),更符合开闭原则
代码实现
抽象模板类
abstract class DataTemplate
{
/**
* 要求每个子类要有自己的日志设置
*/
abstract function setLog();
/**
* 要求每个子类要有自己的点击量设置
*/
abstract function setClick();
/**
* 这里是所有子类公共需要的方法,这个是是获取商品信息,所有类型的商品都需要获取商品详情所以直接定义
*
* 因为所有子类的获取商品信息操作都是一样的 直接定义为 final 禁止修改
*
* 方法的内容是我随便写的(你要根据你自己的业务来重写)
*
* @param $argv
*
* @return array
*/
public final function getInfo($argv)
{
$this->setLog();
$this->setClick();
return ["name" => "id为" . $argv[0] . "的产品"];
}
}
抽象产品
interface Goods
{
public function getList();
}
具体产品
class Book extends DataTemplate implements Goods
{
public function getList()
{
return [
0 => "语文书",
1 => "数学书",
2 => "英语书",
3 => "唐吉坷德",
4 => "尼尔斯骑鹅旅行记",
];
}
function setLog()
{
echo "Boobs setLog<br>";
}
function setClick()
{
echo "Boobs setClick<br>";
}
}
class Dog extends DataTemplate implements Goods
{
public function getList()
{
return [
0 => "金毛",
1 => "二哈",
2 => "萨摩",
3 => "腊肠",
4 => "松狮",
];
}
function setLog()
{
echo "Dogs setLog<br>";
}
function setClick()
{
echo "Dogs setClick<br>";
}
}
调用
这里我是通过工厂模式和注册树模式进行的获取(前两篇文章详细写了关于工厂模式和注册树模式)
Factory::getProduct('Book');
Factory::getProduct('Dog');
var_dump(Dispatch::getInfo(107));
结果
这里为什么会是这样的结果大家可以看一下上两章的内容
Boobs setLog
Boobs setClick
Dogs setLog
Dogs setClick
array (size=2)
0 =>
array (size=1)
'name' => string 'id为107的产品' (length=17)
1 =>
array (size=1)
'name' => string 'id为107的产品' (length=17)
网友评论