文档章节

PHP 工厂模式 实例讲解

大唐6777
 大唐6777
发布于 2017/05/23 20:37
字数 1175
阅读 2
收藏 0

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

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

复制代码
1 采用封装方式
 2 
 3 <?php
 4     class Calc{
 5         /**
 6          * 计算结果
 7          *
 8          * @param int|float $num1
 9          * @param int|float $num2
10          * @param string $operator
11          * @return int|float
12          */
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,'+');//打印:5 41 echo $test->calculate(5,0,'/');//打印:您输入有误:除数不能为0 42 ?>
复制代码

优点:以上代码使用了面向对象的封装特性,只要有了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 ?>

如果帮到了您,可以支持一下,谢谢您的支持!
复制代码

本文转载自:http://www.cnblogs.com/datang6777/p/6893865.html

共有 人打赏支持
大唐6777
粉丝 0
博文 28
码字总数 3378
作品 0
海淀
程序员
系统架构技能之设计模式-单件模式

一、开篇 其实我本来不是打算把系统架构中的一些设计模式单独抽出来讲解的,因为很多的好朋友也比较关注这方面的内容,所以我想通过我理解及平时项目中应用到的一 些常见的设计模式,拿出来给...

wbf961127
2017/11/12
0
0
编程中的那些套路——关于单例模式

该文章属于《编程中的那些经典套路——设计模式汇总》系列,并且以下内容基于语言PHP 在设计模式中,单例模式和工厂模式)可以说是使用的最普遍的设计模式了,所以掌握此种模式尤为重要。 单...

gzchen
08/27
0
0
代理模式(Proxy Pattern):动态代理 - 最易懂的设计模式解析

前言 今天我来全面总结开发中最常用的设计模式 - 代理模式中的动态代理模式 其他设计模式介绍 1分钟全面了解“设计模式” 单例模式(Singleton) - 最易懂的设计模式解析 简单工厂模式(Sim...

Carson_Ho
04/09
0
0
编程中的那些经典套路——设计模式汇总

在正式阅读前,我先谈谈我们该用什么姿势和心态学习设计模式: 如果你还没有过多的编程经验(泛指半年以下),我建议你把它当做小说来看,能看懂多少是多少,因为半年以下经验的程序员用到设...

gzchen
08/27
0
0
php各种设计模式简单实践思考

前言 我一直觉得什么框架,版本,甚至语言对于一个coder来说真的不算什么,掌握一个特别高大上的一个框架或者是一个新的,少众的语言真的不算什么,因为你可以,我要花时间也可以,大家都是这...

michaelgbw
2016/06/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

#mysql50# not Exist

data 目录有中文名称,可能是复制的"复件...."

少年不搬砖老大徒伤悲
18分钟前
1
0
在yii2中,让你action参数支持POST数据的小方法

我们先来看一段代码 class RaController extends Controller { public $enableCsrfValidation = false; public function actionSay($username = '',$city = ''){ echo "{$......

阿北2017
27分钟前
2
0
macOS 10.14 Mojave

在近日发布的 macOS 10.14 Mojave 操作系统中,有人发现它(在某些机型中)悄然禁用了先前的「次像素平滑渲染」选项,导致部分(尤其是使用非高分辨率显示器)用户觉得字体比先前的更细更难看...

火力全開
32分钟前
1
0
 实现分布式锁的正确姿势

实现分布式锁的正确姿势 原理分析 最近看到好多博主都在推分布式锁,实现方式很多,基于db、redis、zookeeper。zookeeper方式实现起来比较繁琐,这里我们就谈谈基于redis实现分布式锁的正确实...

DemonsI
36分钟前
1
0
微信小程序 、支付宝小程序、百度小程序和钉钉e应用的汇总

2018年9月25日 百度小程序开放企业申请 微信小程序:现在微信小游戏都热火朝天了,而且已经有了云开发,包括提供的能力、文档、社区等都相对完善,也有相关的变现方式; 支付宝小程序:https...

to_be_better
39分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部