PHP中“简单工厂模式”实例代码讲解


Posted in PHP onSeptember 04, 2012

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

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

PHP中“简单工厂模式”实例代码讲解

采用封装方式

<?php 
class Calc{ 
/** 
* 计算结果 
* 
* @param int|float $num1 
* @param int|float $num2 
* @param string $operator 
* @return int|float 
*/ 
public function calculate($num1,$num2,$operator){ 
try { 
$result=0; 
switch ($operator){ 
case '+': 
$result= $num1+$num2; 
break; 
case '-': 
$result= $num1-$num2; 
break; 
case '*': 
$result= $num1*$num2; 
break; 
case '/': 
if ($num2==0) { 
throw new Exception("除数不能为0"); 
} 
$result= $num1/$num2; 
break; 
return $result; 
} 
}catch (Exception $e){ 
echo "您输入有误:".$e->getMessage(); 
} 
} 
} 
$test=new Calc(); 
// echo $test->calculate(2,3,'+');//打印:5 
echo $test->calculate(5,0,'/');//打印:您输入有误:除数不能为0 
?>

优点:以上代码使用了面向对象的封装特性,只要有了include这个类,其他页面就可以随便使用了
缺点:无法灵活的扩展和维护
比如:想要增加一个“求余”运算,需要在switch语句块中添加一个分支语句,代码需要做如下改动
添加分支语句
<?php 
class Calc{ 
public function calculate($num1,$num2,$operator){ 
try { 
$result=0; 
switch ($operator){ 
//......省略...... 
case '%': 
$result= $num1%$num2; 
break; 
//......省略...... 
} 
}catch (Exception $e){ 
echo "您输入有误:".$e->getMessage(); 
} 
} 
} 
?>

代码分析:用以上方法实现给计算器添加新的功能运算有以下几个缺点
①需要改动原有的代码块,可能会在为了“添加新功能”而改动原有代码的时候,不小心将原有的代码改错了
②如果要添加的功能很多,比如:‘乘方',‘开方',‘对数',‘三角函数',‘统计',或者添加一些程序员专用的计算功能,比如:And, Or, Not, Xor,这样就需要在switch语句中添加N个分支语句。想象下,一个计算功能的函数如果有二三十个case分支语句,代码将超过一屏,不仅令代码的可读性大大降低,关键是,为了添加小功能,还得让其余不相关都参与解释,这令程序的执行效率大大降低
解决途径:采用OOP的继承和多态思想
简单工厂模式的初步实现
<?php 
/** 
* 操作类 
* 因为包含有抽象方法,所以类必须声明为抽象类 
*/ 
abstract class Operation{ 
//抽象方法不能包含函数体 
abstract public function getValue($num1,$num2);//强烈要求子类必须实现该功能函数 
} 
/** 
* 加法类 
*/ 
class OperationAdd extends Operation { 
public function getValue($num1,$num2){ 
return $num1+$num2; 
} 
} 
/** 
* 减法类 
*/ 
class OperationSub extends Operation { 
public function getValue($num1,$num2){ 
return $num1-$num2; 
} 
} 
/** 
* 乘法类 
*/ 
class OperationMul extends Operation { 
public function getValue($num1,$num2){ 
return $num1*$num2; 
} 
} 
/** 
* 除法类 
*/ 
class OperationDiv extends Operation { 
public function getValue($num1,$num2){ 
try { 
if ($num2==0){ 
throw new Exception("除数不能为0"); 
}else { 
return $num1/$num2; 
} 
}catch (Exception $e){ 
echo "错误信息:".$e->getMessage(); 
} 
} 
} 
?>

这里采用了面向对象的继承特性,首先声明一个虚拟基类,在基类中指定子类务必实现的方法(getValue())
分析:通过采用面向对象的继承特性,我们可以很容易就能对原有程序进行扩展,比如:‘乘方',‘开方',‘对数',‘三角函数',‘统计'等等。
<?php 
/** 
* 求余类(remainder) 
* 
*/ 
class OperationRem extends Operation { 
public function getValue($num1,$num2){ 
return $num1%$num12; 
} 
} 
?>

我们只需要另外写一个类(该类继承虚拟基类),在类中完成相应的功能(比如:求乘方的运算),而且大大的降低了耦合度,方便日后的维护及扩展
现在还有一个问题未解决,就是如何让程序根据用户输入的操作符实例化相应的对象呢?
解决办法:使用一个单独的类来实现实例化的过程,这个类就是工厂
代码如下:
<?php 
/** 
* 工程类,主要用来创建对象 
* 功能:根据输入的运算符号,工厂就能实例化出合适的对象 
* 
*/ 
class Factory{ 
public static function createObj($operate){ 
switch ($operate){ 
case '+': 
return new OperationAdd(); 
break; 
case '-': 
return new OperationSub(); 
break; 
case '*': 
return new OperationSub(); 
break; 
case '/': 
return new OperationDiv(); 
break; 
} 
} 
} 
$test=Factory::createObj('/'); 
$result=$test->getValue(23,0); 
echo $result; 
?>

原创文章,转载请注明出处:http://www.cnblogs.com/hongfei/
PHP 相关文章推荐
php程序之die调试法 快速解决错误
Sep 17 PHP
php中模拟POST传递数据的两种方法分享
Sep 16 PHP
解析web文件操作常见安全漏洞(目录、文件名检测漏洞)
Jun 29 PHP
destoon实现VIP排名一直在前面排序的方法
Aug 21 PHP
ThinkPHP中的create方法与自动令牌验证实例教程
Aug 22 PHP
ThinkPHP 表单自动验证运用示例
Oct 13 PHP
php简单操作mysql数据库的类
Apr 16 PHP
php用正则判断是否为数字的方法
Mar 25 PHP
微信公众号开发之获取位置信息php代码
Jun 13 PHP
php生成二维码不保存服务器还有下载功能的实现代码
Aug 09 PHP
thinkPHP和onethink微信支付插件分享
Aug 11 PHP
Laravel Eloquent分表方法并使用模型关联的实现
Nov 25 PHP
通过php快速统计某个数据库中每张表的数据量
Sep 04 #PHP
比较discuz和ecshop的截取字符串函数php版
Sep 03 #PHP
Windows下部署Apache+PHP+MySQL运行环境实战
Aug 31 #PHP
关于UEditor编辑器远程图片上传失败的解决办法
Aug 31 #PHP
php数组一对一替换实现代码
Aug 31 #PHP
PHP 利用AJAX获取网页并输出的实现代码(Zjmainstay)
Aug 31 #PHP
PHP的简易冒泡法代码分享
Aug 28 #PHP
You might like
php字符串截取的简单方法
2013/07/04 PHP
php读取目录及子目录下所有文件名的方法
2014/10/20 PHP
PHP中addslashes()和stripslashes()实现字符串转义和还原用法实例
2016/01/07 PHP
php mysql like 实现多关键词搜索的方法
2016/10/29 PHP
php进程(线程)通信基础之System V共享内存简单实例分析
2019/11/09 PHP
JS应用之禁止抓屏、复制、打印
2008/02/21 Javascript
JS自定义功能函数实现动态添加网址参数修改网址参数值
2013/08/02 Javascript
详解JavaScript函数绑定
2013/08/18 Javascript
单元选择合并变色示例代码
2014/05/26 Javascript
分析了一下JQuery中的extend方法实现原理
2015/02/27 Javascript
js中split和replace的用法实例
2015/02/28 Javascript
javascript实现简单的鼠标拖动效果实例
2015/04/10 Javascript
深入理解js generator数据类型
2016/08/16 Javascript
Vue.js实现移动端短信验证码功能
2017/03/29 Javascript
nodejs multer实现文件上传与下载
2017/05/10 NodeJs
bootstrap模态框示例代码分享
2017/05/17 Javascript
React如何将组件渲染到指定DOM节点详解
2017/09/08 Javascript
JS实现图片放大镜插件详解
2017/11/06 Javascript
微信小程序使用npm支持踩坑
2018/11/07 Javascript
JavaScript中的回调函数实例讲解
2019/01/27 Javascript
layui table表格数据的新增,修改,删除,查询,双击获取行数据方式
2019/11/14 Javascript
JavaScript 自定义html元素鼠标右键菜单功能
2019/12/02 Javascript
推荐下python/ironpython:从入门到精通
2007/10/02 Python
浅谈Python程序与C++程序的联合使用
2015/04/07 Python
Python基于列表模拟堆栈和队列功能示例
2018/01/05 Python
Django中反向生成models.py的实例讲解
2018/05/30 Python
python全栈要学什么 python全栈学习路线
2019/06/28 Python
python实现静态web服务器
2019/09/03 Python
Python使用re模块验证危险字符
2020/05/21 Python
Urban Outfitters美国官网:美国生活方式品牌
2016/08/26 全球购物
购买原创艺术品:Zatista
2019/11/09 全球购物
护士实习生自我鉴定范文
2013/12/10 职场文书
个人求职信范文分享
2014/01/31 职场文书
反四风个人对照检查材料思想汇报
2014/09/25 职场文书
个人收入证明格式
2015/06/24 职场文书
Java中的Kafka为什么性能这么快及4大核心详析
2022/09/23 Java/Android