php设计模式之简单工厂模式

来源:互联网 发布:网络与新媒体论文选题 编辑:程序博客网 时间:2024/05/01 21:03

简单工厂模式:
①抽象基类:类中定义抽象一些方法,用以在子类中实现
②继承自抽象基类的子类:实现基类中的抽象方法
③工厂类:用以实例化对象

看完文章再回头来看下这张图,效果会比较好

复制代码
 1 采用封装方式 2  3 <?php 4     class Calc{ 5         /** 6          * 计算结果 7          * 8          * @param int|float $num1 9          * @param int|float $num210          * @param string $operator11          * @return int|float12          */13         public function calculate($num1,$num2,$operator){14             try {15                 $result=0;16                 switch ($operator){17                     case '+':18                         $result= $num1+$num2;19                         break;20                     case '-':21                         $result= $num1-$num2;22                         break;23                     case '*':24                         $result= $num1*$num2;25                         break;26                     case '/':27                         if ($num2==0) {28                             throw new Exception("除数不能为0");29                         }30                         $result= $num1/$num2;31                         break;32                 }
33 return $result;34 }catch (Exception $e){35 echo "您输入有误:".$e->getMessage();36 }37 }38 }39 $test=new Calc();40 // echo $test->calculate(2,3,'+');//打印:541 echo $test->calculate(5,0,'/');//打印:您输入有误:除数不能为042 ?>
复制代码

优点:以上代码使用了面向对象的封装特性,只要有了include这个类,其他页面就可以随便使用了

缺点:无法灵活的扩展和维护
比如:想要增加一个“求余”运算,需要在switch语句块中添加一个分支语句,代码需要做如下改动

复制代码
 1 添加分支语句 2  3 <?php 4     class Calc{ 5         public function calculate($num1,$num2,$operator){ 6             try { 7                 $result=0; 8                 switch ($operator){ 9                     //......省略......10                     case '%':11                         $result= $num1%$num2;12                         break;13                     //......省略......14                 }15             }catch (Exception $e){16                 echo "您输入有误:".$e->getMessage();17             }18         }19     }20 ?>
复制代码

代码分析:用以上方法实现给计算器添加新的功能运算有以下几个缺点

①需要改动原有的代码块,可能会在为了“添加新功能”而改动原有代码的时候,不小心将原有的代码改错了
②如果要添加的功能很多,比如:‘乘方’,‘开方’,‘对数’,‘三角函数’,‘统计’,或者添加一些程序员专用的计算功能,比如:And, Or, Not, Xor,这样就需要在switch语句中添加N个分支语句。想象下,一个计算功能的函数如果有二三十个case分支语句,代码将超过一屏,不仅令代码的可读性大大降低,关键是,为了添加小功能,还得让其余不相关都参与解释,这令程序的执行效率大大降低
解决途径:采用OOP的继承和多态思想

复制代码
 1 简单工厂模式的初步实现 2  <?php 3      /** 4       * 操作类 5       * 因为包含有抽象方法,所以类必须声明为抽象类 6       */ 7      abstract class Operation{ 8          //抽象方法不能包含函数体 9          abstract public function getValue($num1,$num2);//强烈要求子类必须实现该功能函数10      }11      /**12       * 加法类13       */14      class OperationAdd extends Operation {15          public function getValue($num1,$num2){16              return $num1+$num2;17          }18      }19      /**20       * 减法类21       */22      class OperationSub extends Operation {23          public function getValue($num1,$num2){24              return $num1-$num2;25          }26      }27      /**28       * 乘法类29       */30      class OperationMul extends Operation {31          public function getValue($num1,$num2){32              return $num1*$num2;33          }34      }35      /**36       * 除法类37       */38      class OperationDiv extends Operation {39          public function getValue($num1,$num2){40              try {41                  if ($num2==0){42                      throw new Exception("除数不能为0");43                  }else {44                      return $num1/$num2;45                  }46              }catch (Exception $e){47                  echo "错误信息:".$e->getMessage();48              }49          }50      }51  ?>
复制代码

这里采用了面向对象的继承特性,首先声明一个虚拟基类,在基类中指定子类务必实现的方法(getValue())

分析:通过采用面向对象的继承特性,我们可以很容易就能对原有程序进行扩展,比如:‘乘方’,‘开方’,‘对数’,‘三角函数’,‘统计’等等。

复制代码
<?php    /**     * 求余类(remainder)     *     */    class OperationRem extends Operation {        public function getValue($num1,$num2){            return $num1%$num12;        }    }?>
复制代码

我们只需要另外写一个类(该类继承虚拟基类),在类中完成相应的功能(比如:求乘方的运算),而且大大的降低了耦合度,方便日后的维护及扩展

现在还有一个问题未解决,就是如何让程序根据用户输入的操作符实例化相应的对象呢?
解决办法:使用一个单独的类来实现实例化的过程,这个类就是工厂
代码如下:


 1 <?php 2     /** 3      * 工程类,主要用来创建对象 4      * 功能:根据输入的运算符号,工厂就能实例化出合适的对象 5      * 6      */ 7     class Factory{ 8         public static function createObj($operate){ 9             switch ($operate){10                 case '+':11                     return new OperationAdd();12                     break;13                 case '-':14                     return new OperationSub();15                     break;16                 case '*':17                     return new OperationSub();18                     break;19                 case '/':20                     return new OperationDiv();21                     break;22             }23         }24     }25     $test=Factory::createObj('/');26     $result=$test->getValue(23,0);27     echo $result;28 ?>
复制代码


0 0