PHP设计模式之策略模式

PHP设计模式之策略模式

策略模式,又称为政策模式,属于行为型的设计模式。php

Gof类图及解释

GoF定义:定义一系列的算法,把它们一个个封装起来,而且使它们能够相互替换。本模式使得算法可独立于使用它的客户而变化 。git

GoF类图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())。一样的,我不用关心他们的具体实现,我只要监督那个和咱们联系的渠道商就能够啦,是否是很省心!测试

完整代码:github.com/zhangyue050…优化

实例

依然仍是短信功能,具体的需求能够参看简单工厂模式中的讲解,可是这回咱们使用策略模式来实现!this

短信发送类图

短信发送策略模式版

完整源码:github.com/zhangyue050…

<?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的中间件就是这货的典型的实现哦!!

相关文章
相关标签/搜索