PHP设计模式之策略者模式

发布时间:2017-04-26编辑:lianpenglin阅读(1527)

    策略模式:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

    封装:把行为用接口封装起来,我们可以把那些经常变化的部分,从当前的类中单独取出来,用接口进行单独的封装。

    互相替换:我们封装好了接口,通过指定不同的接口实现类进行算法的变化。


    下面我来举个例子详细说明下:

    比如我们有一个页面实现了简单计算器的功能,普通写法需要我们根据传过来的符号,通过if/else来判断具体是哪一种计算符号,代码如下:

    <?php
    //简单计算器普通写法实现
    $op = $_POST['op'];//计算器的符号:加减乘除
    $num1 = $_POST['num1'];//第一个参与计算的数字
    $num2 = $_POST['num2'];//第二个参与计算的数字
    if($op == 'add'){
        return $num1 + $num2;
    }elseif ($op == 'sub'){
        return $num1 - $num2;
    }elseif ($op == 'mul') {
        return $num1 * $num2;
    } elseif ($op == 'div') {
        return $num1 / $num2;
    } else {
        return "未找到计算符号";
    }

    通过代码可以看到,这样子写出的代码,扩展性比较差,如果多一个计算符号就需要多一个elseif的判断,下面我们看一下用了策略模式之后的代码:

    <?php
    /*
     *PHP策略模式 ,已计算器为例
     */
    //定义一个计算器接口
    interface Math {
        public function calc($op1,$op2);
    }
    
    //加法类
    class MathAdd implements Math {
        
        public function calc($op1, $op2){
            return $op1 + $op2;
        }
    }
    //减法类
    class MathSub implements Math {
        /**
         * {@inheritDoc}
         * @see Math::calc()
         */
        public function calc($op1, $op2)
        {
            // TODO Auto-generated method stub
            return $op1 - $op2;
        }
    }
    //乘法类
    class MathMul implements Math {
        /**
         * {@inheritDoc}
         * @see Math::calc()
         */
        public function calc($op1, $op2)
        {
            // TODO Auto-generated method stub
            return $op1 * $op2;
        }
    }
    //除法类
    class MathDiv implements Math{
        /**
         * {@inheritDoc}
         * @see Math::calc()
         */
        public function calc($op1, $op2)
        {
            // TODO Auto-generated method stub
            return $op1 / $op2;
        }
    }
    //一个虚拟的计算器
    class Cmath {
        public $cecl;
        public function __construct($op)
        {
           $cecl = 'Math'.$op;
           $this->cecl = new $cecl;
        }
        
        public function cecl($op1,$op2)
        {
            return $this->cecl->calc($op1,$op2);
        }
        
    }
    
    //初始化虚拟计算器类
    $math = new Cmath('Add');
    echo $math->cecl(1, 5);

    通过策略模式重写之后的代码,我们可以看到,所有的计算我们只需和虚拟计算器类,Cmath打交到就可以,Cmath会根据我们传入的不同参数,实例化不同的计算方法类进行计算,当有新的计算符号时,我们只需新建一个计算类,实现Math接口即可。

    总的来说,我们在开发中的设计原则如下:

    1.找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起;

    2.针对接口编程,不针对实现编程;

    3.多用组合,少用继承;


标签php

如果对你有用打赏一下吧!