侧边栏壁纸
博主昵称
流苏小筑

步伐虽小,密而不止

PHP与设计模式:策略模式详解与实战 写一篇博客

2022年05月21日 16阅读 0评论 0点赞

PHP设计模式:策略模式详解与实战 写一篇博客

在实际开发中,我们常会遇到一种场景:同一功能需要根据不同条件选择不同的算法或行为。为了避免使用大量的 if-else 或 switch-case 结构,策略模式(Strategy Pattern)提供了一种更加灵活和可扩展的解决方案。本文将详细讲解策略模式的概念、结构,以及如何在PHP中实现策略模式,并通过案例演示其实际应用。


1. 什么是策略模式?

  • 定义
    定义了一组同类型的算法,在不同的类中封装起来,可以灵活选择调用哪种算法,从而使算法的变化独立于使用它们的客户端(即算法的调用者)。
  • 特点
    分离算法:将算法的定义与使用分离。
    动态切换:可以在运行时选择或替换算法。
    遵循开闭原则:添加新策略不需要修改现有代码。
  • 适用场景
    需要对同一功能提供多种算法实现。
    运行时需要根据不同条件选择不同的算法。

    希望避免使用大量的条件分支语句。

2. 策略模式的组成

策略模式包含以下组件:

1.策略接口(Strategy):定义所有策略的公共接口。
2.具体策略(ConcreteStrategy):实现策略接口的多个具体算法。
3.上下文类(Context):维护对策略对象的引用,负责与客户端交互,并将请求委托给具体策略。


3. PHP实现策略模式

<?php

  /**
 * 策略模式
 */

  /**
 * 计算器接口
 */
  interface Math {
  public function calculate($val1, $val2);
  }

  /**
 * 加法运算
 */
  class Add implements Math {
  public function calculate($val1, $val2) {
    return $val1 + $val2;
  }
  }

  /**
 * 减法运算
 */
  class sum implements Math {
    public function calculate($val1, $val2) {
      return $val1 - $val2;
    }
  }

/**
 * 乘法运算
 */
class mult implements Math {
  public function calculate($val1, $val2) {
    return $val1 * $val2;
  }
}

/**
 * 除法运算
 */
class div implements Math {
  public function calculate($val1, $val2) {
    return $val1 / $val2;
  }
}

/**
 * 虚拟计算器类:关联上下文
 */
class Cmath {
  protected $calculate;

  public function __construct($type) {
    $this->calculate = new $type;
  }

  public function calculate($val1, $val2) {
    return $this->calculate->calculate($val1, $val2);
  }
}

$cmath = new Cmath('add');
echo $cmath->calculate(3, 3);

5. 优缺点分析

  • 优点
    算法独立:每种算法封装在独立的类中,避免了使用复杂的条件语句。
    扩展性强:新增策略时无需修改上下文类和客户端代码。
    动态切换:可以在运行时轻松替换策略。
  • 缺点
    类数量增加:每个策略都需要定义一个独立的类,可能导致类的数量增多。
    上下文复杂性:上下文类需要维护对策略的引用。

6. 实际应用场景

电商系统中可以通过策略模式实现多种支付方式的选择。

<?php

// 支付策略接口
interface PaymentStrategy {
    public function pay(float $amount): void;
}

// 微信支付策略
class WeChatPayStrategy implements PaymentStrategy {
    public function pay(float $amount): void {
        echo "Paid $amount using WeChat Pay." . PHP_EOL;
    }
}

// 支付宝支付策略
class AlipayStrategy implements PaymentStrategy {
    public function pay(float $amount): void {
        echo "Paid $amount using Alipay." . PHP_EOL;
    }
}

// 信用卡支付策略
class CreditCardStrategy implements PaymentStrategy {
    public function pay(float $amount): void {
        echo "Paid $amount using Credit Card." . PHP_EOL;
    }
}

// 客户端代码
class PaymentContext {
    private PaymentStrategy $strategy;

    public function __construct(PaymentStrategy $strategy) {
        $this->strategy = $strategy;
    }

    public function setStrategy(PaymentStrategy $strategy): void {
        $this->strategy = $strategy;
    }

    public function executePayment(float $amount): void {
        $this->strategy->pay($amount);
    }
}

// 测试
$paymentContext = new PaymentContext(new WeChatPayStrategy());
$paymentContext->executePayment(100.0);

$paymentContext->setStrategy(new AlipayStrategy());
$paymentContext->executePayment(200.0);

$paymentContext->setStrategy(new CreditCardStrategy());
$paymentContext->executePayment(300.0);
?>
0

—— 评论区 ——

昵称
邮箱
网址
取消
博主栏壁纸
博主头像 流苏小筑

步伐虽小,密而不止

133 文章数
27 标签数
16 评论量