简介
场景
某个功能需要从多种算法中根据条件选择一种时,有两个方案:
- 将所有算法硬编码到代码中,然后通过条件语句进行选择
- 使用策略模式使系统可以灵活地选择算法,并可以灵活添加新算法
如果条件是固定的,比如根据星期几来选择算法,则可以通过条件语句硬编码。但是如果条件可能增加,可以使用策略模式。
模式定义
定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。
每个封装不同算法的类称为策略(Strategy)类。
模式特点
策略模式包含三个角色:
- Context:环境类
- Strategy:抽象策略类
- ConcreteStrategy:具体策略类
优缺点
- 策略模式将算法的定义和使用分离,符合开放封闭原则,易于扩展
- 调用者可以自己决定使用哪个算法,灵活性提供的同时,使用难度也增大
PHP 代码示例
对于国际贸易,结算时,每个国家的税费计算方法都不同:
<?php
abstract class TaxStrategy
{
abstract public function calculate(array $arr);
}
class CNTax extends TaxStrategy
{
public function calculate(array $arr)
{
return 0.1 * $arr['fee'];
}
}
class FRTax extends TaxStrategy
{
public function calculate(array $arr)
{
return 0.2 * $arr['fee'];
}
}
class SalesOrder
{
private $taxStrategy;
public function __construct(TaxStrategy $s) {
$this->taxStrategy = $s;
}
public function calcTax() {
$context = array(
'fee' => 100,
);
$val = $this->taxStrategy->calculate($context); // 多态调用
echo $val.PHP_EOL;
}
}
$cn = new CNTax();
$so = new SalesOrder($cn);
$so->calcTax();
$fr = new FRTax();
$so = new SalesOrder($fr);
$so->calcTax();