策略模式(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));
}
}