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 相关文章推荐
一个查看session内容的函数
Oct 09 PHP
php 采集书并合成txt格式的实现代码
Mar 01 PHP
php写的简易聊天室代码
Jun 04 PHP
PHP 使用MySQL管理Session的回调函数详解
Jun 21 PHP
ThinkPHP中URL路径访问与模块控制器之间的关系
Aug 23 PHP
PHP中使用SimpleXML检查XML文件结构实例
Jan 07 PHP
PHP的serialize序列化数据以及JSON格式化数据分析
Oct 10 PHP
PHP上传图片时判断上传文件是否为可用图片的方法
Oct 20 PHP
基于thinkPHP类的插入数据库操作功能示例
Jan 06 PHP
老生常谈PHP面向对象之注册表模式
May 26 PHP
PHP中phar包的使用教程
Jun 14 PHP
Laravel中的chunk组块结果集处理与注意问题
Aug 15 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
ThinkPHP控制器详解
2015/07/27 PHP
thinkPHP实现基于ajax的评论回复功能
2018/06/22 PHP
PHP var关键字相关原理及使用实例解析
2020/07/11 PHP
URI、URL和URN之间的区别与联系
2006/12/20 Javascript
关于文本限制字数的js代码
2007/04/02 Javascript
jquery实现图片等比例缩放以及max-width在ie中不兼容解决
2013/03/21 Javascript
Angular.js与Bootstrap相结合实现表格分页代码
2016/04/12 Javascript
jQuery实现的tab标签切换效果示例
2016/09/05 Javascript
jquery  实现轮播图详解及实例代码
2016/10/12 Javascript
通过V8源码看一个关于JS数组排序的诡异问题
2017/08/14 Javascript
nginx配置React静态页面的方法教程
2017/11/03 Javascript
详解vue中点击空白处隐藏div的实现(用指令实现)
2018/04/19 Javascript
解决nodejs的npm命令无反应的问题
2018/05/17 NodeJs
基于JS实现web端录音与播放功能
2019/04/17 Javascript
微信小程序中为什么使用var that=this
2019/08/27 Javascript
layui 数据表格复选框实现单选功能的例子
2019/09/19 Javascript
layui 上传图片 返回图片地址的方法
2019/09/26 Javascript
JavaScript利用键盘码控制div移动
2020/03/19 Javascript
openlayers实现地图测距测面
2020/09/25 Javascript
js实现头像上传并且可预览提交
2020/12/25 Javascript
Python中random模块用法实例分析
2015/05/19 Python
Python随机生成身份证号码及校验功能
2018/12/04 Python
日本网路线上商品代购服务:转送JAPAN
2016/08/05 全球购物
美国手机支架公司:PopSockets
2019/11/27 全球购物
简单说说tomcat的配置
2013/05/28 面试题
工作会议主持词
2014/03/17 职场文书
后备干部培训方案
2014/05/22 职场文书
中国梦演讲稿3分钟
2014/08/19 职场文书
大学生国庆节65周年演讲稿范文
2014/09/25 职场文书
2014最新实习证明模板
2014/10/02 职场文书
降价通知函
2015/04/23 职场文书
2016春季幼儿园开学寄语
2015/12/03 职场文书
如何理解PHP核心特性命名空间
2021/05/28 PHP
Python中requests做接口测试的方法
2021/05/30 Python
python 爬取天气网卫星图片
2021/06/07 Python
JAVA API 实用类 String详解
2021/10/05 Java/Android