為了實現(xiàn)以觀測模式為基礎(chǔ)的錯誤記錄句柄,首先我們注意到作為觀測者的FileErrorLogger類和EmailErrorLogger類什么也不能做。那么,F(xiàn)ileErrorLogger類是如何向一個文件寫出錯信息,EmailErrorLogger類又如何發(fā)送電子郵件的? 接下來,讓我來看看用來實現(xiàn)觀測模式的技術(shù)細節(jié),然后,再集中精力來看看該模式的主體――ErrorHandler的細節(jié)。最后,再寫一些錯誤處理函數(shù)來調(diào)用這個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)。它可以通過函數(shù)Attach()來注冊各種錯誤信息觀測者,而set_error_handler()函數(shù)就是一個指向ErrorHandler類的函數(shù)。最后,當一個錯誤信息被觸發(fā)后,所有的觀測者都會得到通知。
為了使這次觀測的操作生效,你的測試必須能證明所有的這些操作(將錯誤信息寫入日志,利用電子郵件發(fā)送錯誤信息)都能得到執(zhí)行,并且能正常工作。簡而言之,讓我們來看看一系列簡單的測試。(和這個實例有關(guān)的其他更多實例,可以在本書附帶的源代碼中找到)
這里有FileErrorLogger類聯(lián)合測試的一部分代碼:它用來測試當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()函數(shù)創(chuàng)建了一個文件指針,指向一個名為“test.log”的新文件。并且,將該指針保存在變量$_fh中,這個可寫的文件指針將作為一個變量傳遞給FileErrorlogger對象的實例,進行測試。變量$content的值將傳遞給函數(shù)write(),并且,在存儲結(jié)束后,還將用來被檢查$content的值是否確實被正確寫入test.log文件中。
(這個測試要求PHP必須具有向那個新建的test.log中寫數(shù)據(jù)的權(quán)限。)
下面的一些代碼也許可以幫助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類能真正發(fā)送電子郵件的呢?是的,你可以打開你的收件箱,看看其中是否有新郵件,就知道了。但是,那就不是一個全自動的測試了。 或者說,這個測試就只是偽模式的一個不錯的替代方案。(至于如何創(chuàng)建一個控制郵件的類,將作為一個練習留給讀者的。詳細信息,請參考第6章The MockObject Pattern 或參考FakeMail項目http://sf.net/projects/fakemail/.)
出處:phpchina
責任編輯:bluehearts
上一頁 php設(shè)計模式介紹之觀測模式 [1] 下一頁 php設(shè)計模式介紹之觀測模式 [3]
◎進入論壇網(wǎng)絡(luò)編程版塊參加討論
|