策略模式(Strategy)

echoou發表於2021-01-04

策略模式(Strategy)

策略模式定義

策略模式是把演算法,封裝起來。使得使用演算法和使用演算法環境分離開來,當演算法發生改變時,我們之需要修改客戶端呼叫演算法,和增加一個新的演算法封裝類。比如超市收銀,收營員判斷顧客是否是會員,當顧客不是會員時候,按照原價收取顧客購買商品費用,當顧客是會員的時候,滿100減5元。

策略模式的優點

  • 降低程式碼耦合度,
  • 增加程式碼重用性,當需要實現新的演算法時候,只需要修改演算法部分,而不需要對上下文環境做任何改動;
  • 增加程式碼可閱讀性,避免使用if....else巢狀,造成難以理解的邏輯;

策略模式的缺點

  • 當策略過多的時候,會增加很多類檔案;

程式碼實現

Cashier.php

<?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);
    }
}

CustomerAbstract.php

<?php


namespace App\Creational\Strategy;


abstract class CustomerAbstract
{
    abstract public function pay($price);
}

NormalCustomer.php

<?php


namespace App\Creational\Strategy;


class NormalCustomer extends CustomerAbstract
{

    public function pay($price)
    {
        return $price;
    }
}

VipCustomer.php

<?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));
    }
}

相關文章