php设计模式之策略模式

概念:策略模式属于行为设计模式的一种,

此设计模式就是为了封装算法使用,但是在实际的使用过程中,我们其实是可以用他来封装任何类型的策略,只要根据业务的不同规则进行设计

代码如下

 

<?php

/**
 * 定义抽象策略类
 */
abstract class StrategyAbstract{
    abstract public function doAction($data);
    public function print($a){
        foreach ($a as $v){
            echo $v.PHP_EOL;
        }
    }
}


class StrategyA extends StrategyAbstract{
    public function doAction($data){
        echo "执行具体策略类:".__CLASS__.PHP_EOL;
    }

}

class StrategyB extends StrategyAbstract{
    public function doAction($data){
        $this->print($data);
        echo "执行具体策略类:".__CLASS__.PHP_EOL;
    }
}


/**
 * 定义策略工厂类
 */

class StrategyFind{

    /**
     * 策略实例
     * @var StrategyAbstract
     */
    private  static $strategy_mode;

    /**
     * 定义执行方法
     * @var string
     */
    private static $action='get';

    public function __construct($mode)
    {
        $this->initStrategy($mode);
    }

    /**
     * 开始执行具体策略
     * @param string $action  策略方法
     * @param $arg  策略
     */
    public function get(string $action='',...$arg)
    {
        try {
            $action = $action ?? static::getAction();

            $this->strategy_mode->$action($arg);
        }catch (Exception $exception){
            throw new Exception("策略执行失败");
        }
    }

    /**
     * 获取执行方法
     * @return string
     */
    private static function getAction() :string
    {
        return static::$action;
    }

    /**
     * 替换已经存在的策略
     * @throws Exception
     */
    public function replace($mode)
    {
        static::$strategy_mode = null;
        $this->initStrategy();
    }

    /**
     * 初始化策略实例对象
     * @param $mode
     */
    public function initStrategy($mode){
        try {
            $class = new ReflectionClass($mode);
            static::$strategy_mode = $class->newInstance();
        } catch (ReflectionException $e) {
            throw new Exception('不存在的策略类');
        }
    }
}

/**
 * 实例化策略工厂,通过反射获取实例
 * 这个地方的 namespace 可以 定义一个数组之类的东西,直接做个映射,这样调用策略的时候,不需要管这个类在哪,只需要你指定某一个策略就行了
 * 
 */
$StrategyFind   =  new StrategyFind(StrategyB::class);
$StrategyFind->get('doAction',1,2,3,4);

  

posted @ 2021-08-28 17:15  fianl507  阅读(113)  评论(0)    收藏  举报