政策模式,又稱為政策模式,屬于行為型的設計模式。
Gof類圖及解釋
GoF定義:定義一系列的算法,把它們一個個封裝起來,并且使它們可以互相替換。本模式使得算法可獨立于使用它的客戶而變化 。
GoF類圖
代碼實作
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();
- 注意對比下類圖,基本和簡單工廠模式沒什麼差別
- 政策模式定義的是算法,從概念上看,這些算法完成的都是相同的工作,隻是實作不同,但東西是死的,人是活的,具體想怎麼用,還不是看大家的興趣咯
- 政策模式可以優化單元測試,因為每個算法都有自己的類,是以可以通過自己的接口單獨測試