为了实现以观测模式为基础的错误记录句柄,首先我们注意到作为观测者的FileErrorLogger类和EmailErrorLogger类什么也不能做。那么,FileErrorLogger类是如何向一个文件写出错信息,EmailErrorLogger类又如何发送电子邮件的? 接下来,让我来看看用来实现观测模式的技术细节,然后,再集中精力来看看该模式的主体――ErrorHandler的细节。最后,再写一些错误处理函数来调用这个ErrorHandler类。
最后用下面的这一段代码来表示:
// PHP4 $eh =& getErrorHandlerInstance(); $eh->attach(new EmailErrorLogger(‘jsweat_php@yahoo.com’)); $eh->attach(new FileErrorLogger(fopen(‘error.log’,’w’)));
set_error_handler(‘observer_error_handler’);
// ... later trigger_error(‘this is an error’);
ErrorHandler类是一种单件模式(参考第4章:The Singleton Pattern)。它可以通过函数Attach()来注册各种错误信息观测者,而set_error_handler()函数就是一个指向ErrorHandler类的函数。最后,当一个错误信息被触发后,所有的观测者都会得到通知。
为了使这次观测的操作生效,你的测试必须能证明所有的这些操作(将错误信息写入日志,利用电子邮件发送错误信息)都能得到执行,并且能正常工作。简而言之,让我们来看看一系列简单的测试。(和这个实例有关的其他更多实例,可以在本书附带的源代码中找到)
这里有FileErrorLogger类联合测试的一部分代码:它用来测试当FileErrorlogger类被某个对象实例化时,是否具有向一个文件写日志的能力。
class FileErrorLoggerTestCase extends UnitTestCase { var $_fh; var $_test_file = ‘test.log’;
function setup() { @unlink($this->_test_file); $this->_fh = fopen($this->_test_file, ‘w’); }
function TestRequiresFileHandleToInstantiate() { /* ... */ }
function TestWrite() { $content = ‘test’.rand(10,100); $log =& new FileErrorLogger($this->_fh);
$log->write($content); $file_contents = file_get_contents($this->_test_file); $this->assertWantedPattern(‘/’.$content.’$/’, $file_contents); }
function TestWriteIsTimeStamped() { /* ... */ }
}
在这个测试中, setup()函数创建了一个文件指针,指向一个名为“test.log”的新文件。并且,将该指针保存在变量$_fh中,这个可写的文件指针将作为一个变量传递给FileErrorlogger对象的实例,进行测试。变量$content的值将传递给函数write(),并且,在存储结束后,还将用来被检查$content的值是否确实被正确写入test.log文件中。
(这个测试要求PHP必须具有向那个新建的test.log中写数据的权限。)
下面的一些代码也许可以帮助FileErrorLogger类通过测试。
class FileErrorLogger { var $_fh; function FileErrorLogger($file_handle) { $this->_fh = $file_handle; } function write($msg) { fwrite($this->_fh, date(‘Y-m-d H:i:s: ‘).$msg); } }
一个类似的测试代码可以使EmailErrorLogger类生效。
class EmailErrorLoggerTestCase extends UnitTestCase { function TestEmailAddressFirstConstructorParameter() { $log =& new EmailErrorLogger; $this->assertErrorPattern(‘/missing.*1/i’); }
function TestMail() { $log =& new EmailErrorLogger(‘jsweat_php@yahoo.com’); $log->mail(‘test message’); } }
接下来,通过这个测试的EmailErrorLogger类的代码如下:
class EmailErrorLogger { var $_addr; var $_subject;
function EmailErrorLogger($addr, $subject=’Application Error Message’) { $this->_addr = $addr; $this->_subject = $subject; }
function mail($msg) { mail($this->_addr ,$this->_subject ,date(‘Y-m-d H:i:s: ‘).$msg); } }
你是怎样确定EmailErrorLogger类能真正发送电子邮件的呢?是的,你可以打开你的收件箱,看看其中是否有新邮件,就知道了。但是,那就不是一个全自动的测试了。 或者说,这个测试就只是伪模式的一个不错的替代方案。(至于如何创建一个控制邮件的类,将作为一个练习留给读者的。详细信息,请参考第6章The MockObject Pattern 或参考FakeMail项目http://sf.net/projects/fakemail/.)
出处:phpchina
责任编辑:bluehearts
上一页 php设计模式介绍之观测模式 [1] 下一页 php设计模式介绍之观测模式 [3]
◎进入论坛网络编程版块参加讨论
|