2019-02-15 发布 ┊ 1377 人浏览 ┊ 0 人评论 ┊ 来源:原创 ┊
收藏┊
分享至
策略模式的定义解析
策略模式(Strategy Pattern):定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化,也称为政策模式(Policy)。
核心思想是这句: 让算法独立于使用它的客户而变化 。
这是什么意思?也就是说实现一个功能,有多个方法,而选择这个方法的控制权不要交给客户端,也就说了,我换了实现方法,客户端是不需要改代码的~
那么要做到这样子,必然提供给客户端的一个稳定的调用类(称为环境类),首先调用这个类能够产生一个具体算法的实例,其次这个调用类,还需要公布一个接口,让客户端调用实现具体功能。
那么做到以上,无论实现多少种方法,客户端的调用都是不变的。控制权都在这个调用类里边,由它来决定到底采用哪种算法。
下面来接着说算法部分。如果需要 环境类 提供一个实现具体功能的接口,那么这些算法必然实现了一个公共接口(称为抽象策略类)。才能确保有相同的方法提供出来。然后具体的算法都要实现这个接口。这也就是上面定义中的 将每一个算法封装起来 每一个具体的算法称为:具体策略类
不知道这个解释大家清楚定义了没有,如果还不清楚,看类图
类图演示
策略模式包含的角色如下:
Context: 环境类
Strategy: 抽象策略类
ConcreteStrategy: 具体策略类
策略模式是使用非常广泛的一个设计模式。他很好的提现了:控制反转、依赖注入等思想。
下面结合聚合支付的例子(支付宝+微信)演示一下
策略模式PHP代码实现
在整个模式中,Strategy 起着承上启下的作用。先定义一个策略接口,里面
规范一个必须要实现的方法,
环境类依赖这个接口进行编程
interface ChargeStrategy
{
public function charge();
}
下面接着写算法的实现。还是以支付宝支付、微信支付为例。对于用户来说他要实现的功能是支付。那么支付又有多种选择(多种算法)。但是客户端不需要做出选择,他把这个权利让 环境类 去选择。这样子客户端就简单了。所有的算法需要实现 策略类接口。
// 支付宝策略类
class AliCharge implements ChargeStrategy
{
public function charge()
{
// 完成支付宝的相关逻辑
}
}
// 微信策略类
class WxCharge implements ChargeStrategy
{
public function charge()
{
// 完成微信的相关逻辑
}
}
final class ChargeContext
{
/**
* @var ChargeStrategy $charge
*/
private $charge;
public function initInstance($channel)
{
if ($channel == 'ali') {
$this->charge = new AliCharge;
} elseif ($chananel == 'wx') {
$this->charge = new WxCharge;
} else {
$this->charge = null;
}
}
public function charge()
{
if (is_null($this->charge)) {
exit('初始化错误');
}
$this->charge->charge();
}
}
//以上就基本完成了,再看客户端的调用
// 获取用户选择的支付方式
$channel = trim($_GET['channel']);
$context = new ChargeContext();
// 初始化支付实例
$context->initInstance($channel);
// 调用功能
$context->charge();
这个模式很好的实现了开闭原则。例如:现在需要新增加一个PayPal支付,那么只需要添加一个PayPal的策略算法。在ChargeContext中把对应的实例初始化加进去,其他地方都不需要动~