《PHP设计模式介绍》第六章 伪对象模式(4)_PHP教程
推荐:《PHP设计模式介绍》第五章 注册模式我们通常认为避免使用全局变量是一种好的选择,因此,对象经常被作为参数从一段代码传递到另一段。但是传递实例的一个问题就是对象有时候不知道将要传递给谁——?经过一个函数后才被传
让我们从注销功能上开始:
class PageDirectorTestCase extends UnitTestCase { |
在这段代码中,response是个伪对象,然而,一旦在Response::redirect()方法中调用了exit(),脚本将会停止执行。由于伪对象的存在,你可以核实方法是否被调用和方法传回了什么参数,且不会产生任何负面影响——如脚本停止——或被实际执行。
下面是是一些帮助你认识测试功能的代码:
class PageDirector { // ... function run() { $this->processLogin(); if ($this->isLoggedIn()) { $this->showPage( new UserLogin($this->session->get(‘user_name’))); } else { $this->showLogin(); } $this->response->display(); } function processLogin() { if (array_key_exists(‘clear’, $_REQUEST)) { $this->session->clear(‘user_name’); $this->response->redirect(SELF); } } } |
最后是对登录表单的处理进行的测试。
class PageDirectorTestCase extends UnitTestCase { |
如下是实现上面测试所要求特性的代码:
class PageDirector { |
这段程序已经重构而且也有充分的测试,因此可以对其进行一些附加的重构来清除像主脚本访问Session类,查询不经UserLogin类认可的字段而去访问‘user_name’字段,及session被当成资源调用等的小毛病。
当$_REQUEST这个超级变量被封装为一个类似Session类的资源以便与伪对象的创建时,为何让代码访问它?这段 代码有很多问题:但它毕竟是某种人为的用来逐渐了解这些概念的例子,它是为此而被创造的所以你不必深究。
更为重要的是,你已经学会利用伪对象测试模式来分离代码,以及在测试中分离$_SESSION之类的资源和避免相互关联的对象(如包含在Response类中的exit())产生不希望的结果。
问题
使用伪对象来测试代码可以让你分离所开发的代码。你可以消除负面影响和潜在的问题,极大地减少你在整个测试工作中所花的时间。这是一个好消息,因为如果你花在测试上的时间越多,以后就会越省事,并且你也会希望测试不是只做一次,应该能够被重复进行。(译注:这句直译太别扭,所以加了些使其通顺的内容。)
在新重构的程序中仍然会有许多漏洞。比如$_REQUEST变量应该由一个类来封装以便于使用伪对象测试。又如 showLogin()方法的重新调用。再如所有那些addBody()方法的调用看起来是如此混乱。
这种编程风格的另一个缺点是你将无法使用任何所见即所得的HTML编辑工具,这是因为所有HTML代码都被包含在PHP的方法调用中了。为了避免这些限制,你可以加入一个简单的基于PHP的模板机制。你可以这样引入模板文件:
<form method=”post”> Name:<input type=”text” name=”name”> Password:<input type=”password” name=”passwd”> <input type=”submit” value=”Login”> </form> |
然后需要使用一个方法来调用它:
class Response { // ... /** * adds a simple template mechanism to the response class * @param string $template the path and name of the template file * @return void */ function addBodyTemplate($template, $vars=array()) { if (file_exists($template)) { extract($vars); ob_start(); include $template; $this->_body .= ob_get_clean(); } } } |
很明显的,世上没有最完美的模板引擎,但它确实使本章的示例代码精简整洁了。
在GoF中这种按任务进行分隔的概念是被鼓励的:
“分隔设计模式下对象被创建后,其子类的创建过程就可以不再关注了。”
分享:《PHP设计模式介绍》第四章 单件模式几乎所有面向对象的程序中,总有一两个资源被创建出来,在程序应用中持续被共享使用。例如,这样的一个资源,在一个电子商务程序的数据库连接中使用:这个连接在应用程序启动时初始化,程序于是
- 相关链接:
- 教程说明:
PHP教程-《PHP设计模式介绍》第六章 伪对象模式(4)。