前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >php设计模式(二十三):策略模式(Strategy)

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

作者头像
陈大剩博客
发布2023-07-09 14:03:41
2110
发布2023-07-09 14:03:41
举报

策略模式

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

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

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

问题

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

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

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

解决方法

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

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

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

结构

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

代码示例

商场策略接口类

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

具体策略类

代码语言:javascript
复制
/**
 * 折扣类
 */
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 '我是积分返利策略';
    }
}

支付类

代码语言:javascript
复制
/**
 * 支付类
 */
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();
    }
}

客户端使用

代码语言:javascript
复制
/**
 * 折扣
 */
$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;

输出

代码语言:javascript
复制
php Client.php
我是折扣策略
我是积分返利策略
我是购物返券策略

UML

策略模式
策略模式

优缺点

优点

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

缺点

  • 如果的算法极少发生改变,那么没有任何理由引入新的类和接口。使用该模式只会让程序过于复杂。
  • 客户端必须知晓策略间的不同——它需要选择合适的策略。
  • 许多现代编程语言支持函数类型功能,允许在一组匿名函数中实现不同版本的算法。使用这些函数的方式就和使用策略对象时完全相同,无需借助额外的类和接口来保持代码简洁。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-06-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 策略模式
  • 问题
  • 解决方法
  • 结构
  • 代码示例
    • 商场策略接口类
      • 具体策略类
        • 支付类
          • 客户端使用
          • UML
          • 优缺点
            • 优点
              • 缺点
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档