陈大剩博客

php设计模式(二十三):策略模式(Strategy)

  • 陈大剩
  • 2023-06-14 22:48:13
  • 663

策略模式

策略模式又称为:Strategy。策略模式是一种行为设计模式,它能让你定义一系列算法,并将每种算法分别放入独立的类,以使算法的对象能够相互替换。

上文主要是说的可替换的,日常生活中可替换非常常见,如我们去一个地方(西藏)?我们可以骑单车、骑摩托、坐汽车、坐火车、坐飞机等,这些都是我们出行可替换的。

上述:骑单车、骑摩托、坐汽车、坐火车、坐飞机等,每一种就是一种算法,可以由我们自己进行定义。

问题

假设我们向商场的各种商户开发一款商场收银软件,需要对顾客买的商品的单价和数量进行收费,我们针对不同商家,我们需要对顾客购买的商品进行包括但不限于:打折、满减、随机立减。

让人头疼的是,每个商家对这些折扣模式都不一样,A 商家需要打 5 折,B 商家打 8 折,C 商家需要达到 100 满减 5 元。

这样我们不得写 N 中折扣模式,臃肿且使用最多的可能就那么几种,只是每个商家的价格模式不一样,那我们有没有一张策略能使每个商家都可以使用呢?

解决方法

我们可以使用策略模式,提供一个可替换的公共模板,每个商家可以在这个模式进行独家定制化,定制一套属于自己的方案,替换成自己的方案即可,这样既影响不到其他商家,也不会使整个软件臃肿。

阿这,这不是我们生活中常常遇到吗?提供一个模板给你,其他你自己来改,难不成这个是设计模式?

是的,其实设计模式和我们生活也息息相关,只是我们一直在做没有留意而已。

结构

Strategy:策略接口类,提供一个通用的策略类型(模版)。
Discount、PointRebate、PointRebate:具体策略类,提供不同的策略算法(不同的折扣类型)。
Payment:支付类,传入不同的策略对象实现不同的策略算法(收银类)。

代码示例

商场策略接口类

/**
 * 商场策略接口类
 */
interface Strategy
{
    /**
     * 执行策略具体逻辑,如:满减、折扣、返利
     * @return mixed
     * @author chendashengpc
     */
    public function execute();
}

具体策略类

/**
 * 折扣类
 */
class Discount implements Strategy
{
    public function execute()
    {
        // todo 业务代码
        return '我是折扣策略';
    }
}

/**
 * 积分返利类
 */
class PointRebate implements Strategy
{
    public function execute()
    {
        // todo 业务代码
        return '我是积分返利策略';
    }
}

/**
 * 积分返利类
 */
class PointRebate implements Strategy
{
    public function execute()
    {
        // todo 业务代码
        return '我是积分返利策略';
    }
}

支付类

/**
 * 支付类
 */
class Payment
{
    private Strategy $strategy;

    /**
     * 初始化函数
     * @param Strategy $strategy
     */
    public function __construct(Strategy $strategy)
    {
        $this->strategy = $strategy;
    }

    /**
     * 支付策略
     * @return mixed
     * @author chendashengpc
     */
    public function payStrategy()
    {
        return $this->strategy->execute();
    }
}

客户端使用

/**
 * 折扣
 */
$payment = new Payment(new Discount());
echo $payment->payStrategy() . PHP_EOL;

/**
 * 积分返利
 */
$payment = new Payment(new PointRebate());
echo $payment->payStrategy() . PHP_EOL;

/**
 * 购物返券
 */
$payment = new Payment(new ShoppingVoucher());
echo $payment->payStrategy() . PHP_EOL;

输出

php Client.php
我是折扣策略
我是积分返利策略
我是购物返券策略

UML

策略模式

优缺点

优点

  • 可以在运行时切换对象内的算法。
  • 可以将算法的实现和使用算法的代码隔离开来。
  • 可以使用组合来代替继承。
  • 开闭原则。无需对上下文进行修改就能够引入新的策略。

缺点

  • 如果的算法极少发生改变,那么没有任何理由引入新的类和接口。使用该模式只会让程序过于复杂。
  • 客户端必须知晓策略间的不同——它需要选择合适的策略。
  • 许多现代编程语言支持函数类型功能,允许在一组匿名函数中实现不同版本的算法。使用这些函数的方式就和使用策略对象时完全相同,无需借助额外的类和接口来保持代码简洁。
分享到:
0

说点儿什么吧

头像

表情

本站由陈大剩博客程序搭建 | 湘ICP备2023000975号| Copyright © 2017 - 陈大剩博客 | 本站采用创作共用版权:CC BY-NC 4.0

站长统计| 文章总数[109]| 评论总数[9]| 登录用户[22]| 时间点[112]

logo

登入

社交账号登录