文档章节

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
海淀
程序员
私信 提问
《PHP设计模式大全》系列分享专栏

《PHP设计模式大全》已整理成PDF文档,点击可直接下载至本地查阅 https://www.webfalse.com/read/201739.html 文章 php设计模式介绍之编程惯用法第1/3页 php设计模式介绍之值对象模式第1/5页...

kaixin_code
11/06
0
0
系统架构技能之设计模式-单件模式

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

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

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

gzchen
08/27
0
0
编程中的那些经典套路——设计模式汇总

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

gzchen
08/27
0
0
Javascript设计模式与开发实践详见(一:单例模式)

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设...

littl_Prince
2016/04/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

java.util.Concurrent.Semaphore 源码

类图 源码: package java.util.concurrent;import java.util.Collection;import java.util.concurrent.locks.AbstractQueuedSynchronizer;public class Semaphore implements ja......

狼王黄师傅
17分钟前
2
0
Kubernetes里的secret最基本的用法

Secret解决了密码、token、密钥等敏感数据的配置问题,使用Secret可以避免把这些敏感数据以明文的形式暴露到镜像或者Pod Spec中。 Secret可以以Volume或者环境变量的方式使用。 使用如下命令...

JerryWang_SAP
昨天
2
0
2018-11-20学习笔记

1. python数据类型: 给变量赋值什么样的值,变量就是什么样的类型 给变量赋值整数,变量就是整数类型 给变量赋值字符串,变量就是字符串类型 123 和“123”一样吗? 在python中 单引号 与双...

laoba
昨天
1
0
使用 React 和 Vue 创建相同的应用,他们有什么差异?

在工作中应用 Vue 之后,我对它有了相当深刻的理解。 不过,俗话说「外国的月亮比较圆」,我好奇「外国的」 React 是怎么样的。 我阅读了 React 文档并观看了一些教程视频,虽然它们很棒,但...

阿K1225
昨天
4
0
2天闭门培训|以太坊智能合约从入门到实战(北京)

2天培训 16个课时 探寻技术原理,精通以太坊智能合约开发 以太坊智能合约是现在应用的最广泛的区块链应用开发方式,HiBlock区块链社区针对以太坊智能合约的学习特别推出2天闭门研修班,通过2...

HiBlock
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部