天天看點

PHP設計模式之政策模式

政策模式,又稱為政策模式,屬于行為型的設計模式。

Gof類圖及解釋

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

GoF類圖
PHP設計模式之政策模式
代碼實作
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

執行個體

依然還是短信功能,具體的需求可以參看簡單工廠模式中的講解,但是這回我們使用政策模式來實作!

短信發送類圖
<?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();      
  • 注意對比下類圖,基本和簡單工廠模式沒什麼差別
  • 政策模式定義的是算法,從概念上看,這些算法完成的都是相同的工作,隻是實作不同,但東西是死的,人是活的,具體想怎麼用,還不是看大家的興趣咯
  • 政策模式可以優化單元測試,因為每個算法都有自己的類,是以可以通過自己的接口單獨測試

繼續閱讀