15
05月
2020
策略模式
模式定义
策略模式(Strategy),又叫算法簇模式,定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化,即封装变化的算法。
策略模式的优势
易于扩展,增加一个新的策略只需要添加一个具体的策略类即可,基本不需要改变原有的代码,符合开放封闭原则
使用策略模式可以避免使用多重条件转移语句(if ... else)
策略类之间可以自由切换,由于策略类都实现同一个接口,所以使它们之间可以自由切换 每个策略类使用一个策略类,符合单一职责原则
客户端与策略算法解耦,两者都依赖于抽象策略接口,符合依赖反转原则
客户端不需要知道都有哪些策略类,符合最小知识原则
策略模式的缺陷
策略模式,当策略算法太多时,会造成很多的策略类
客户端不知道有哪些策略类,不能决定使用哪个策略类,可以考虑使用IOC容器和依赖注入的方式来解决
代码示例
Strategy\ComparatorInterface.class.php
<?php
namespace Strategy;
interface ComparatorInterface
{
public function compare($a, $b);
}Strategy\DateComparator.class.php
<?php
namespace Strategy;
class DateComparator implements ComparatorInterface
{
public function compare($a, $b)
{
$aDate = strtotime($a['date']);
$bDate = strtotime($b['date']);
if($aDate == $bDate) {
return 0;
} else {
return $aDate < $bDate ? -1 : 1;
}
}
}Strategy\IdComparator.class.php
<?php
namespace Strategy;
class IdComparator implements ComparatorInterface
{
public function compare($a, $b)
{
if($a['id'] == $b['id']) {
return 0;
} else {
return $a['id'] < $b['id'] ? -1 : 1;
}
}
}Strategy\Context.class.php
<?php
namespace Strategy;
class Context
{
private $strategy;
public function __construct($strategy)
{
$this->strategy = $strategy;
}
public function getCompare($a, $b)
{
return $this->strategy->compare($a, $b);
}
}Strategy\StrategyTest.php
<?php
spl_autoload_register(function ($className){
$className = str_replace("\\", "/", $className);
include $className . ".class.php";
});
use Strategy\IdComparator;
use Strategy\DateComparator;
use Strategy\Context;
$a = array(
'id' => 1,
'date' => '2020-05-12'
);
$b = array(
'id' => 1,
'date' => '2020-05-13'
);
$strategy = new Context(new IdComparator());
echo $strategy->getCompare($a, $b);
echo "\n";
$strategy = new Context(new DateComparator());
echo $strategy->getCompare($a, $b);
echo "\n";测试示例:
php Strategy/StrategyTest.php 输出: 0 -1
总结
策略模式将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。通常,策略模式适用于当一个应用程序需要实现一种特定的服务或者功能,而且该程序有多种实现方式时使用。
代码地址:https://github.com/798256478/design-patterns/tree/master/Strategy