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