php教程:php设计模式介绍之伪对象模式
日期:2008年7月3日 作者: 查看:[大字体 中字体 小字体]-
《PHP设计模式介绍》第六章 伪对象模式
面向对象的编程之所以丰富多彩,部分是由于对象间的相互联系与作用。一个单一的对象就能封装一个复杂的子系统,使那些很复杂的操作能够通过一些方法的调用而简化。(无所不在的数据库连接就是这样的一个对象实例。)
然而经常有这样的情况,对象间的交互性是如此复杂以至于我们不得不面对类似“先有鸡还是先有蛋”这样伤脑筋的问题:如何创建并测试这样一个对象,他要么依赖于很多已创建的对象,要么依赖于其他一些难以意识到的情况,如整个数据库的创建和测试。
问题
如何分隔并测试一个与其他对象和资源有关的代码段?又如何再创建一个或多个对象、程序来验证你的代码能正常运行?
解决方案
当用situ(或在一个仿真的程序环境中)测试一个对象代价不菲或困难重重时,就可用伪对象来模拟这个行为。伪对象有同真实对象一样的接口,但却能提供预编译响应,能跟踪方法调用,并验证调用次序。
伪对象是测试的“特别力量”。他们被秘密训练,渗透进目标代码,模拟并监视通信方式,回报结果。伪对象有助于查找和消除程序漏洞并能支持更多正常调试环境下的“防危险”操作。
注:The ServerStub
伪对象模式是另一种测试模式ServerStub的扩展。ServerStub模式替代一个资源并返回其方法所调用的相应值。当其参与指定次序的方法的调用时ServerStub就成了伪对象。其并非是一个设计模式
本章与其他章不同,因为伪对象是一个测试模式而不是设计模式。这类似于一个附加的章节,但对它的使用 确实很值得你纳入到编码进程中。另一个不同是我们不再关注这个模式如何编码之类的基础问题,而是强调 如何在SimpleTest中使用伪对象。
本章先举一个非常简单的例子来示范SimpleTest下伪对象的基本机制。然后向你演示如何使用伪对象帮助重构已有代码与如何测试新的解决方案。
样本代码
伪对象是对象在测试中的一个替代品,用它测试代码更加简便。例如,替代一个真实的数据连接——这个真实的数据连接由于一些原因而不能实际连接——你就可以创建一个伪对象来模拟。这意味着伪对象需要准确地回应代码中所调用的相同的应用程序接口。
让我们创建一个伪对象来替代一个简单的名为Accumulator的类,这是一个求和的类。如下是最初的Accumulator类:
这个类中add()函数先累加值到$total变量中,再交由total()函数返回 。 一个简单的累加也可以如下面这样(下面的代码被编写为一个函数,但它也可以写成一个类)。
第一个函数calc_total()用一个累加的动作求一系列值的和。下面是简单的测试:
让我们关注第二个例子。假设实现一个真实的累加动作的代价很大。那么用一个简单的对象来替代它并回应相关代码就是很好的做法了。使用SimpleTest,你可以用如下代码创建一个伪累加动作:
为了使用伪对象,具有代表性的做法是你亲自写一个新类(并不要求马上做)。幸运的是,SimpleTest有一种容易的手段来实现 Mock::generate() 方法。
在上面的例子中,这种手段创建了一个名为MockAccumulator的类来响应所有Accumulator类的方法。另外,伪累加的动作还有其他手段来操作伪对象自身的实例。例如 setReturnValue()。给出一个方法名和一个值,
setReturnValue()就可以改变伪对象而给出对应方法所调用的值。因此,这条语句$amount->setReturnValue(‘total’, 200)返回200而不论何时调用了total()方法。
一旦进行完初始化工作后,你可以传递MockAccumulator类到calc_tax()函数来演示一个在真实的Accumulator对象空间中的动作。
如果你止步于此——即用一个对象来返回所调用函数的“封装”响应——你只是使用了ServerStub模式。 用伪对象来验证方法的调用不限于此,因为它可以不限次序与次数。
下面是一个通过对象来验证“数据流”的例子:
这里expectOnce()方法使用了一个字符串,它包含你想调用的方法名 。而tally()实际上用来检查你的想法是否实现。这里,如果MockAccumulator::total()只调用一次或不调用,测试将失败。
在很多情况下你可以使用伪对象的”跟踪”特性。例如,如果你传递一个具有三个值的数组到calc_total(),Accumulator::add()是否也如你所想的调用了三次呢?
那,这里发生了什么?传递调用的测试失败。SimpleTest的错误消息如下所示:
错误消息指出了尽管add() 方法被调用三次,但expectOnce()却一次也没用到。取代expectOnce()的可行方法是使用expectCallCount()。
伪对象扮演了一个演员的角色——这个角色由SeverStub提供合理的测试数据来响应方法的调用——并且作为一个评判的角色,验证所调用的方法是否符合预想。
重构已有程序
下面让我们用伪对象来帮助重构一个已有程序。考虑一个简单的脚本,它可以模拟你在无数的PHP程序中所期望的行为:例如一个当检查到你未登录时要求登录的页面;与此类似的还有表单处理页面;它能在成功登录后显示不同内容并提供登出的功能。 让我们写一个这样的页面。首先,对还未登录的用户显示一个登录表单。
接着,显示登录成功后的内容:
加入表单处理的功能,session(会话)开始,还有登出的功能,整体看起来应该类似这样:
重构这个程序的一个目的应该是使其成为一个“易于测试”的程序。基于这个目的,如果你还选择一些PHP中的方便特性——如超级全局变量——你将失去测试上的简洁性。
例如,如果你直接就用了$_SESSION,即意味着只有一种途径可以测试这个代码,就是改变$_SESSION。如果你忘了将$_SESSION改回先前已知的状态,各种测试间就会互相干扰。
一个好的解决方法是封装$_SESSION到另一个类中,传递所封装类的实例到任何想要访问$_SESSION的对象。如果你创建了一个已封装对象的伪对象用于测试,你能够完全控制对象对所调用方法的响应(就像ServerStub那样)并且你能核实它是如何调用的(那正是创建伪对象的目的)。
具备了这个思想,让我们看看如何封装$_SESSION之类的全局变量。
类Session封装了全局变量$_SESSION。对类SESSION的测试非常类似于对前期的已注册的类的改良测试(参见第5章),但是却无任何通过参数获得或设置相应值的意图。
你也许注意到了构造函数调用了Session::init()方法。为什么这个方法不是构造函数的一部分呢?这样分开的好处是你能静态调用它并确保session已经开始。下面是一个如何使用该类的例子。
大部分测试方面的文献很推崇伪对象并建议你亲自写一个。如果你打算那样做,开始测试时你就只需要充实那些你需要的方法就可以了。譬如,一个用于处理代码的ServerStub的Session类很可能是这样的:
幸运的是,你可以用SimpleTest来避免那些易范的错误。Mock::generate()方法允许你创建一个类来实例化或动态地配置你想要的结果。
注:伪对象技术
- [1] [2] [3] [4] 下一页
-
- php教程:php设计模式介绍之伪对象模式 相关文章:
- ·Excel:强大的公式函数
- ·各种文件后缀名与打开方式大全
- ·恢复exe文件打开方式,所有exe文件无法打开
- ·常见视频文件格式有哪些
- ·显示器工厂模式的进入方法集锦
- ·JSP文件下载的几种方式
- ·黑客必学:DOS状态下命令方式入侵系统
- ·使用 XSL 样式表无法查看 XML 输入
- ·『隐现式QQ空间开门效果3款』
- ·Excel“条件格式”公式实例
- php教程:php设计模式介绍之伪对象模式 相关软件
- ·金山打字 2006 正式版
- ·QQ堂 V2.1 Beta2 Build16 宠爱正式版
- ·腾讯QQ2007 新珊瑚虫正式版
- ·深山红叶PE工具箱 嫦娥一号纪念版 V30 正式版
- ·WisMencoder V1.99 正式版
- ·MaxDOS V5.8s U盘正式版
- ·侠盗猎车手 简体中文正式GBA版
- ·flv格式转3gp格式专用软件(微视转码工具)
- ·《铁血联盟2》黄金版TBS汉化补丁正式版
- ·拳皇KOF2001正式版
- 特别声明:本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作
- 者.文章版权归文章原始作者所有.对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转
- 载的文章有版权问题请联系编辑人员,我们尽快予以更正. 转载请注明来源:http://www.hackhome.com
上一篇:Flash游戏开发教程:第五节
精品推荐
热点TOP10
- ·Swt常用控件中文教程
- ·什么是LDAP
- ·一个Struts实现分页,增删改查,Tiles,国际化的DEMO
- ·ajax+php无刷新二级联动下拉菜单(省市联动)源码
- ·如何设置Tomcat的JVM虚拟机内存大小
- ·一棵php的类树(支持无限分类)
- ·php删除文件夹及其文件夹下所有文件
- ·自己写的一个PHP上传类
- ·用JFreeChart画统计分析柱状图
- ·域名查询代码公布
- ·TomCat 多虚拟站点配置
- ·PHP 优化配置——加速你的PHP程序
- ·学习教程:Java Annotation 高级应用
- ·PHP程序员都应该会用的五个工具
- ·JSTL 入门:表达式语言
- ·最近写的一个PHP操作Access类(PHP+ODBC+Access)
- ·基于Windows环境下的PHP开发环境搭建
- ·PHP模板引擎SMARTY
- ·php.ini配置,php.ini 中的 php-5.2.0 配置指令详解
- ·PHP环境搭建最新方法
特别推荐
- ·如何在本地安装调试运行PHP程序?
- ·PHP面向对象分析设计的61条军规
- ·php教程:php设计模式介绍之伪对象模式
- ·php教程:php设计模式介绍之工厂模式
- ·php入门交流:鼓励学习PHP的新手
- ·PHP程序员都应该会用的五个工具
- ·文件上传类
- ·PHP的类--功能齐全的发送邮件类
- ·用PHP编写PDF文档生成器
- ·php生成EXCEL的东东
- ·PHP编程与应用
- ·PHP网上调查系统
- ·一个多文件上传的例子(原创)
- ·用IE远程创建Mysql数据库的简易程序
- ·一次编写,随处运行
- ·JSP单页面网站文件管理器
- ·Apache2的httpd.conf翻译
- ·使用PHP的Socket写的POP3类
- ·一棵php的类树(支持无限分类)
- ·PHP实现简单线性回归之数学库的重要性
