更进一步说,你能随心所欲的设置何种方法被调用以及调用多少次。你甚至可以验证那些根本不该被调用的方法。
下面是一个扩展型的测试,它用来建立和验证那些复杂的设计。
class PageDirectorTestCase extends UnitTestCase { function testSomethingWhichUsesSession() { $session =& new MockSession($this); $session->setReturnValue(‘isValid’, true); $session->setReturnValue(‘get’, 1); $session->expectOnce(‘isValid’, array(‘user_id’)); $session->expectOnce(‘get’, array(‘user_id’)); $session->expectNever(‘set’); // the actual code which uses $session $session->tally(); } }
使用伪对象的原因很多,方法也多样化。但在我们继续前,让我们把另外的一些类加入进来,使其来龙去脉更加清楚。
接下来的一部分是重构已有脚本,创建一个用于检查用户是否有相应权限的名为UserLogin的类。
class UserLogin { var $_valid=true; var $_id; var $_name; function UserLogin($name) { switch (strtolower($name)) { case ‘admin’: $this->_id = 1; $this->_name = ‘admin’; break; default: trigger_error(“Bad user name ‘$name’”); $this->_valid=false; } } function name() { if ($this->_valid) return $this->_name; } function Validate($user_name, $password) { if (‘admin’ == strtolower($user_name) && ‘secret’ == $password) { return true; } return false; } }
(在一个实际的程序中,你应当按照如上所示的逻辑来查询相应的数据表,这种小而且编写起来费神的类体现了你将如何运用ServerStub来组织代码———ServerStub是一个小型的表达你想法的类,但它只是在一些限制环境下可用。)
最后一部分是创建响应。为了最终在浏览器中显示,我们必须处理那不断增长的HTML内容,如果必要的话我们也会讨论HTTP重定向。(你也可以执行其他的http头的操作——这样说是为了能构隐藏它——在一个成熟的做法中,但这里使用的是一段更简单的代码,是为了使例子容易理解与关注。)
class Response { var $_head=’’; var $_body=’’; function addHead($content) { $this->_head .= $content; } function addBody($content) { $this->_body .= $content; } function display() { echo $this->fetch(); } function fetch() { return ‘<html>’ .’<head>’.$this->_head.’</head>’ .’<body>’.$this->_body.’</body>’ .’</html>’; } function redirect($url, $exit=true) { header(‘Location: ‘.$url); if ($exit) exit; } }
给出了这些模块后,也是时候将这些新开发的、已测试的组件聚合到一个页面中了。让我们写一个最终的类来协调这个页面的所以行为,取个合适的名字PageDirector。类PageDirector具有一个很简单的运用程序接口:你在实例化后可以用调用它的run()方法。
这个“bootstrap”文件运行新程序时应如下所示:
<?php require_once ‘classes.inc.php’; define(‘SELF’, ‘http://www.example.com/path/to/page.php’); $page =& new PageDirector(new Session, new Response); $page->run(); ?>
该文件包含了所需的已定义类,并为自己定义了一个常量,给PageDirector类(其用于传递类Session 和类Response所依赖的实例来组成构造函数)创建了一个实例来执行PageDirector::run()方法。
出处:phpchina
责任编辑:bluehearts
上一页 php设计模式介绍之伪对象模式 [3] 下一页 php设计模式介绍之伪对象模式 [5]
◎进入论坛网络编程版块参加讨论
|