快捷搜索:  as  2018  FtCWSyGV  С˵  test  xxx  Ψһ  w3viyKQx

澳门新葡亰游戏881:php设计模式介绍之观测模式



一些面向工具的编程要领,供给了一种构建工具间繁杂收集互连的能力。当工具们连接在一路时,它 们就可以互相供给办事和信息。

平日来说,当某个工具的状态发生改变时,你仍旧必要工具之间 能相互通信。然则出于各类缘故原由,你大概并不乐意由于代码情况的改变而对代码做大年夜的改动。大概,你 只想根据你的详澳门新葡亰游戏881细利用情况而改进通信代码。或者,你只想简单的从新构造通信代码来避免类和类之间 的互相依附与互相从属。

问题

当一个工具的状态发生改变时,你若何看护其他工具?是 否必要一个动态规划――一个就像容许脚本的履行一样,容许自由连接的规划?

办理规划

不雅测模式容许一个工具关注其他工具的状态,并且,不雅测模式还为被不雅测者供给了一种不雅测布局 ,或者说是一个主体和一个客体。主体,也便是被不雅测者,可以用来联系所有的不雅测它的不雅测者。客体 ,也便是不雅测者,用来吸收主体状态的改变

不雅测便是一个可被不雅测的类(也便是主题)与一个 或多个不雅测它的类(也便是客体)的协作。不论什么时刻,当被不雅测工具的状态变更时,所有注册过的 不雅测者都邑获得看护。

不雅测模式将被不雅测者(主体)从不雅测者(客体)种分离出来。这样,每个 不雅测者都可以根据主体的变更分手采取各自的操作。(不雅测模式和Publish/Subscribe模式一样,也是一 种有效描述工具间互相感化的模式。)

不雅测模式机动而且功能强大年夜。对付被不雅测者来说,那些查 询哪些类必要自己的状态信息和每次应用那些状态信息的额外资本开销已经不存在了。别的,一个不雅测 者可以在任何相宜的时刻进行注册和取消注册。你也可以定义多个详细的不雅测类,以便在实际利用中执 行不合的操作。

实例代码

举例来说,你可以应用不雅测模式为你的PHP脚原先创建一个更灵 活的记录差错的句柄。由于,默认的差错记录句柄大概只会在屏幕上显示一些掉足信息,然则增强后的 句柄还可以将掉足信息写进一个日志文件中,或澳门新葡亰游戏881将掉足信息写进系统日志之中,或将掉足信息经由过程电子 邮件发送出去,或使用声音申报掉足信息。你以致还可以构造一种有级其余报错规划,只容许向那些已 经为详细的掉足信息注册过的不雅测者申报。从一样平常的警告信息到像数据库掉灵之类的严重掉足信息都可 以申报。

下面,我们用不雅测模式来为PHP创建一系列的类来实现刚才所说的那些功能。新建一个 名为ErrorHandler的类, 它便是不雅测模式的主体,也便是被不雅测者。再建别的两个名为 FileErrorLogger和 EmailErrorLogger的类, 它们是不雅测客体(即不雅测者)。FileErrorLogger类将出 错信息写入日志文件,EmailErrorLogger类使用电子邮件发送掉足信息。在UML中,可以表示如下:

为了实 现以不雅测模式为根基的差错记录句柄,首先我们留意到作为不雅测者的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 (‘observ澳门新葡亰游戏881er_error_handler’);

// ... later

trigger_error(‘this  is an error’);

ErrorHandler类是一种单件模式(参考第澳门新葡亰游戏8814章: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.’$/&rsquo澳门新葡亰游戏881;, $file_contents);

}

function  TestWriteIsTimeStamped() { /* ... */ }

}

您可能还会对下面的文章感兴趣: