策略模式和模板模式(PHP)
2021-10-14 本文已影响0人
嗼念
策略模式
是定义一组算法(策略),将每个算法分别封装起来,让他们可以互相替换,使算法的变化独立于使用他们的代码。
说到这个模式,第一反应就是利用它来避免冗长的 if-else 或 switch 的分支判断,在程序运行时根据配置、用户输入、程序计算结果等方式动态确定使用哪种策略。可以通过使用Map的查表法或者反射的方式去替代分支判断。
策略模式侧重“策略”或“算法”这个特定的应用场景,用来解决根据运行时状态从一组策略中选择不同策略的问题。
使用场景:(举例)
1、不同订单来源对应不用的分佣规则,如直推20%、间推10%、客户经理直销15%三种方式对应三种不同分佣比例的实现。
2、不同来源订单(团购、促销、普通)的不同优惠券使用策略等等。
//策略定义
interface Strategy {
public function algorithminterface() ;
}
class ConcreateStrategyA implements Strategy {
public function algorithminterface() {
// @TODO
echo "A success~ \r\n" ;
}
}
class ConcreateStrategyB implements Strategy {
public function algorithminterface() {
// @TODO
echo "B success~ \r\n" ;
}
}
//策略的创建
class StrategyFactory {
private $strategies = [] ;
public function __construct() {
$this->strategies = [
'A' => new ConcreateStrategyA(),
'B' => new ConcreateStrategyB()
];
}
public function getStrategy(String $type) {
//@TODO 校验
foreach ($this->strategies as $key => $item) {
if ($key == $type) {
return $item ;
}
}
}
}
//策略的使用
$demo = new StrategyFactory() ;
$res = $demo->getStrategy('A') ;
$res->algorithminterface();
$two = $demo->getStrategy('B') ;
$two->algorithminterface();
模板模式
在一个方法中定义一个算法骨架,并将某些步骤延迟到子类中去实现,可以让子类在不改变算法整体结构的情况下,重新定义算法中的某些步骤。
这里的“算法”,我们可以理解为“业务逻辑”。
模板模式的两大作用是复用和扩展,复用是指所有子类都可以复用父类中提供的模板方法的代码。扩展是指通过模板模式提供的功能扩展点,可以在不修改父类代码的情况下扩展功能。
使用场景:(举例)
1、文章分享到不同平台(微信、微博、QQ...),标题、图片、描述、链接等基础数据一致,不同平台分享的api不一样。(感觉适配器模式也好合适...o(╥﹏╥)o )
2、第三方账号注册 。账号注册的大体流程一致,判断是否是新用户,拉取第三方信息(单独的实现步骤延迟到子类实现),存储、绑定手机号操作等
/*
定义通用的流程代码
将可变的部分拆分定义成一个或多个抽象类留给子类去实现
所有子类都可以复用该模板方法定义的流程代码
*/
abstract class AbstractClass {
public final function templateMethod() {
// ....@TODO
$this->method1() ;
// ....@TODO
$this->method2() ;
// ....@TODO
}
//抽象方法1
abstract protected function method1() ;
//抽象方法2
abstract protected function method2() ;
}
//实现父类中抽象方法的子类
class ConCreateClass1 extends AbstractClass {
protected function method1() {
echo "class1-mothod1 implementation~ \r\n" ;
}
protected function method2() {
echo "class1-mothod2 implementation~ \r\n" ;
}
}
//实现父类中抽象方法的子类
class ConCreateClass2 extends AbstractClass {
protected function method1() {
echo "class2-mothod2 implementation~ \r\n" ;
}
protected function method2() {
echo "class2-mothod2 implementation~ \r\n" ;
}
}
// demo
$demo = new ConCreateClass1() ;
$demo->templateMethod() ;
$demo = new ConCreateClass2() ;
$demo->templateMethod() ;