PHP設計模式之策略模式

策略模式,又稱爲政策模式,屬於行爲型的設計模式。php

Gof類圖及解釋

GoF定義:定義一系列的算法,把它們一個個封裝起來,而且使它們能夠相互替換。本模式使得算法可獨立於使用它的客戶而變化 。laravel

GoF類圖git

策略模式

代碼實現github

interface Strategy{
    function AlgorithmInterface();
}

class ConcreteStrategyA implements Strategy{
    function AlgorithmInterface(){
        echo "算法A";
    }
}

class ConcreteStrategyB implements Strategy{
    function AlgorithmInterface(){
        echo "算法B";
    }
}

class ConcreteStrategyC implements Strategy{
    function AlgorithmInterface(){
        echo "算法C";
    }
}

定義算法抽象及實現。算法

class Context{
    private $strategy;
    function __construct(Strategy $s){
        $this->strategy = $s;
    }
    function ContextInterface(){
        
        $this->strategy->AlgorithmInterface();
    }
}

定義執行環境上下文。設計模式

$strategyA = new ConcreteStrategyA();
$context = new Context($strategyA);
$context->ContextInterface();

$strategyB = new ConcreteStrategyB();
$context = new Context($strategyB);
$context->ContextInterface();

$strategyC = new ConcreteStrategyC();
$context = new Context($strategyC);
$context->ContextInterface();

最後,在客戶端按需調用合適的算法。微信

  • 是否是很是簡單的一個設計模式。你們有沒有發現這個模式和咱們最先講過的簡單工廠很是相似
  • 那麼他們的區別呢?
  • 工廠相關的模式屬於建立型模式,顧名思義,這種模式是用來建立對象的,返回的是new出來的對象。要調用對象的什麼方法是由客戶端來決定的
  • 而策略模式屬性行爲型模式,經過執行上下文,將要調用的函數方法封裝了起來,客戶端只須要調用執行上下文的方法就能夠了
  • 在這裏,咱們會發現,須要客戶端來實例化具體的算法類,貌似還不如簡單工廠好用,既然這樣的話,你們何不嘗試一下結合工廠和策略模式一塊兒來實現一個模式呢?
  • 做爲思考題將這個實現留給你們,提示:將Context類的__construct變成一個簡單工廠方法

既然和簡單工廠如此的相像,那麼咱們也按照簡單工廠的方式來講:咱們是一個手機廠商(Client),想找某工廠(ConcreteStrategy)來作一批手機,經過渠道商(Context)向這個工廠下單製造手機,渠道商直接去聯繫代工廠(Strategy),而且直接將生產完成的手機發貨給我(ContextInterface())。一樣的,我不用關心他們的具體實現,我只要監督那個和咱們聯繫的渠道商就能夠啦,是否是很省心!函數

完整代碼:https://github.com/zhangyue0503/designpatterns-php/blob/master/10.strategy/source/strategy.php單元測試

實例

依然仍是短信功能,具體的需求能夠參看簡單工廠模式中的講解,可是這回咱們使用策略模式來實現!學習

短信發送類圖

短信發送策略模式版

完整源碼:https://github.com/zhangyue0503/designpatterns-php/blob/master/10.strategy/source/strategy-message.php

<?php

interface Message
{
    public function send();
}

class BaiduYunMessage implements Message
{
    function send()
    {
        echo '百度雲發送信息!';
    }
}

class AliYunMessage implements Message
{
    public function send()
    {
        echo '阿里雲發送信息!';
    }
}

class JiguangMessage implements Message
{
    public function send()
    {
        echo '極光發送信息!';
    }
}

class MessageContext
{
    private $message;
    public function __construct(Message $msg)
    {
        $this->message = $msg;
    }
    public function SendMessage()
    {
        $this->message->send();
    }
}

$bdMsg = new BaiduYunMessage();
$msgCtx = new MessageContext($bdMsg);
$msgCtx->SendMessage();

$alMsg = new AliYunMessage();
$msgCtx = new MessageContext($alMsg);
$msgCtx->SendMessage();

$jgMsg = new JiguangMessage();
$msgCtx = new MessageContext($jgMsg);
$msgCtx->SendMessage();

說明

  • 注意對比下類圖,基本和簡單工廠模式沒什麼區別
  • 策略模式定義的是算法,從概念上看,這些算法完成的都是相同的工做,只是實現不一樣,但東西是死的,人是活的,具體想怎麼用,還不是看你們的興趣咯
  • 策略模式能夠優化單元測試,由於每一個算法都有本身的類,因此能夠經過本身的接口單獨測試

下期看點

策略模式算是一箇中場休息,後面還有一大半的模式尚未講呢,接下來登場的這位但是近幾年的網紅選手:責任鏈模式。不要告訴我你沒聽過這位的大名,Laravel的中間件就是這貨的典型的實現哦!!

關注公衆號:【硬核項目經理】獲取最新文章

添加微信/QQ好友:【xiaoyuezigonggong/149844827】免費得PHP、項目管理學習資料

知乎、公衆號、抖音、頭條搜索【硬核項目經理】

B站ID:482780532

相關文章
相關標籤/搜索