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 编程的 5个良好习惯
Feb 20 PHP
php连接mssql数据库的几种方法
Feb 21 PHP
php fsockopen伪造post与get方法的详解
Jun 14 PHP
windows下PHP_intl.dll正确配置方法(apache2.2+php5.3.5)
Jan 14 PHP
smarty半小时快速上手入门教程
Oct 27 PHP
PHP两种快速排序算法实例
Feb 15 PHP
php将字符串随机分割成不同长度数组的方法
Jun 01 PHP
PHP查看当前变量类型的方法
Jul 31 PHP
php入门教程之Zend Studio设置与开发实例
Sep 09 PHP
php cookie 详解使用实例
Nov 03 PHP
thinkphp中AJAX返回ajaxReturn()方法分析
Dec 06 PHP
php微信公众号开发之秒杀
Oct 20 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 7编译安装错误:cannot stat ‘phar.phar’: No such file or directory
2017/02/25 PHP
基于php流程控制语句和循环控制语句(讲解)
2017/10/23 PHP
禁止刷新,回退的JS
2006/11/25 Javascript
20条学习javascript的编程规范的建议
2014/11/28 Javascript
JS实现跟随鼠标立体翻转图片的方法
2015/05/04 Javascript
延时加载JavaScript代码提高速度
2015/12/27 Javascript
把多个JavaScript函数绑定到onload事件处理函数上的方法
2016/09/04 Javascript
jQuery插件zTree实现单独选中根节点中第一个节点示例
2017/03/08 Javascript
yarn的使用与升级Node.js的方法详解
2017/06/04 Javascript
利用angular、react和vue实现相同的面试题组件
2018/02/19 Javascript
JS简单实现动态添加HTML标记的方法示例
2018/04/08 Javascript
vue点击按钮实现简单页面的切换
2020/09/08 Javascript
Express 配置HTML页面访问的实现
2020/11/01 Javascript
[01:27]2014DOTA2展望TI 剑指西雅图IG战队专访
2014/06/30 DOTA
[01:07:57]DOTA2-DPC中国联赛 正赛 Ehome vs Magma BO3 第二场 1月19日
2021/03/11 DOTA
Python查询Mysql时返回字典结构的代码
2012/06/18 Python
简介Django框架中可使用的各类缓存
2015/07/23 Python
Python连接PostgreSQL数据库的方法
2016/11/28 Python
详解Python pygame安装过程笔记
2017/06/05 Python
Python生成任意范围任意精度的随机数方法
2018/04/09 Python
django请求返回不同的类型图片json,xml,html的实例
2018/05/22 Python
解决pycharm的Python console不能调试当前程序的问题
2019/01/20 Python
基于python plotly交互式图表大全
2019/12/07 Python
Python实现弹球小游戏
2020/08/01 Python
Django怎么在admin后台注册数据库表
2020/11/14 Python
HTML5 文件域+FileReader 分段读取文件并上传到服务器
2017/10/23 HTML / CSS
ghd澳大利亚官方网站:英国最受欢迎的美发工具品牌
2018/05/21 全球购物
生物化学研究助理员求职信
2013/10/09 职场文书
庆元旦文艺演出主持词
2014/03/27 职场文书
市场拓展计划书
2014/05/03 职场文书
2016年过年放假安排通知
2015/08/18 职场文书
2015年库房管理工作总结
2015/10/14 职场文书
解析MySQL binlog
2021/06/11 MySQL
磁贴还没死, 微软Win11可修改注册表找回Win10开始菜单
2021/11/21 数码科技
「睡美人」爱洛公主粘土人开订
2022/03/22 日漫
分析SQL窗口函数之取值窗口函数
2022/04/21 Oracle