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来自动调用不同服务器上的flash
Oct 09 PHP
使用php4加速网络传输
Oct 09 PHP
解析php中heredoc的使用方法
Jun 17 PHP
php环境下利用session防止页面重复刷新的具体实现
Jan 09 PHP
PHP中的排序函数sort、asort、rsort、krsort、ksort区别分析
Aug 18 PHP
PHP间隔一段时间执行代码的方法
Dec 02 PHP
php上传图片生成缩略图(GD库)
Jan 06 PHP
使用PHP+MySql+Ajax+jQuery实现省市区三级联动功能示例
Sep 15 PHP
PHP开发之归档格式phar文件概念与用法详解【创建,使用,解包还原提取】
Nov 17 PHP
Yii2框架类自动加载机制实例分析
May 02 PHP
PHP如何通过表单直接提交大文件详解
Jan 08 PHP
php常用字符串长度函数strlen()与mb_strlen()用法实例分析
Jun 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
ajax+php控制所有后台函数调用
2015/07/15 PHP
PHP实现的链式队列结构示例
2017/09/15 PHP
PHP之认识(二)关于Traits的用法详解
2019/04/11 PHP
JavaScript与函数式编程解释
2007/04/27 Javascript
JQuery实现倒计时按钮的实现代码
2012/03/23 Javascript
javascript将数组插入到另一个数组中的代码
2013/01/10 Javascript
JavaScript的strict模式与with关键字介绍
2014/02/08 Javascript
jquery实现的下拉和收缩效果示例
2014/08/21 Javascript
介绍JavaScript中Math.abs()方法的使用
2015/06/14 Javascript
解析javascript瀑布流原理实现图片滚动加载
2016/03/10 Javascript
【JS+CSS3】实现带预览图幻灯片效果的示例代码
2016/03/17 Javascript
javascirpt实现2个iframe之间传值的方法
2016/06/30 Javascript
JS判断日期格式是否合法的简单实例
2016/07/11 Javascript
javascript加载xml 并解析各节点的值(实现方法)
2016/10/12 Javascript
通过fastclick源码分析彻底解决tap“点透”
2017/12/24 Javascript
微信小程序自定义组件之可清除的input组件
2018/07/17 Javascript
JS实现点击li标签弹出对应的索引功能【案例】
2019/02/18 Javascript
解决layer.confirm选择完之后消息框不消失的问题
2019/09/16 Javascript
解决vue中的无限循环问题
2020/07/27 Javascript
Python3基础之list列表实例解析
2014/08/13 Python
Python基于回溯法子集树模板解决野人与传教士问题示例
2017/09/11 Python
基于Python socket的端口扫描程序实例代码
2018/02/09 Python
Python3爬取英雄联盟英雄皮肤大图实例代码
2018/11/14 Python
Python2和Python3的共存和切换使用
2019/04/12 Python
python如何读取bin文件并下发串口
2019/07/05 Python
python scatter函数用法实例详解
2020/02/11 Python
基于html5绘制圆形多角图案
2016/04/21 HTML / CSS
世界第一曲奇连锁店:Mrs. Fields Cookies
2017/02/04 全球购物
iHerb中文官网:维生素、保健品和健康产品
2018/11/01 全球购物
Bravofly德国:预订廉价航班和酒店
2019/09/22 全球购物
捷科时代的软件测试笔试题
2015/11/09 面试题
四年大学生活的个人自我评价
2013/12/11 职场文书
2014年服装销售工作总结
2014/11/27 职场文书
不服劳动仲裁起诉书
2015/05/20 职场文书
小学教代会开幕词
2016/03/04 职场文书
Python利用FlashText算法实现替换字符串
2022/03/31 Python