设计模式:策略模式的实际应用


策略模式的定义解析
策略模式(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中把对应的实例初始化加进去,其他地方都不需要动~







分享至
2019-02-15 发布 ┊ 1377 人浏览 ┊ 0 人评论 ┊ 来源:原创 ┊ 收藏
返回顶部