策略模式(Strategy)
策略模式(Strategy)
策略模式定义
策略模式是把算法,封装起来。使得使用算法和使用算法环境分离开来,当算法发生改变时,我们之需要修改客户端调用算法,和增加一个新的算法封装类。比如超市收银,收营员判断顾客是否是会员,当顾客不是会员时候,按照原价收取顾客购买商品费用,当顾客是会员的时候,满100减5元。
策略模式的优点
- 降低代码耦合度,
- 增加代码重用性,当需要实现新的算法时候,只需要修改算法部分,而不需要对上下文环境做任何改动;
- 增加代码可阅读性,避免使用if….else嵌套,造成难以理解的逻辑;
策略模式的缺点
- 当策略过多的时候,会增加很多类文件;
代码实现
<?php
namespace App\Creational\Strategy;
class Cashier
{
private $cutomer;
public function setStrategy(CustomerAbstract $customer)
{
$this->cutomer = $customer;
}
public function getMoney($price)
{
return $this->cutomer->pay($price);
}
}
<?php
namespace App\Creational\Strategy;
abstract class CustomerAbstract
{
abstract public function pay($price);
}
<?php
namespace App\Creational\Strategy;
class NormalCustomer extends CustomerAbstract
{
public function pay($price)
{
return $price;
}
}
<?php
namespace App\Creational\Strategy;
class VipCustomer extends CustomerAbstract
{
public function pay($price)
{
return $price - floor($price/100)*5;
}
}
测试代码
StrategyTest.php
<?php
/**
* 策略模式
* Class StrategyTest
*/
class StrategyTest extends \PHPUnit\Framework\TestCase
{
public function testCustomer()
{
$price = 100;
$vipCutomer = new \App\Creational\Strategy\VipCustomer();
$normalCustomer = new \App\Creational\Strategy\NormalCustomer();
$cashier = new \App\Creational\Strategy\Cashier();
$cashier->setStrategy($vipCutomer);
$this->assertEquals(95, $cashier->getMoney($price));
$cashier->setStrategy($normalCustomer);
$this->assertEquals(100, $cashier->getMoney($price));
}
}