装饰器的一个优点是你可以将他们串在一起(使用)。Invalid装饰器仅仅知道:它正在包装一个组件:它不必关心组件是否是一个TextInput, Select,或者是一个有标签的被装饰版本的组件 。
这导致了下一个合理的测试用例:
class WidgetTestCase extends UnitTestCase { // ... function testInvalidLabeled() { $text =& new Invalid( new Labeled( ‘Email’ ,new TextInput(‘email’))); $output = $text->paint(); $this->assertWantedPattern(‘~<b>Email:</b> <input~i’, $output); $this->assertWantedPattern( ‘~^<span class=”invalid”>.*</span>$~i’, $output); } }
有了Invalid装饰器,我们来处理FormHandler::validate() 方法:
class FormHandlerTestCase extends UnitTestCase { // ... function testValidateMissingName() { $post =& new Post; $post->set(‘fname’, ‘Jason’); $post->set(‘email’, ‘jsweat_php@yahoo.com’); $form = FormHandler::build($post); $this->assertFalse(FormHandler::validate($form, $post)); $this->assertNoUnwantedPattern(‘/invalid/i’, $form[0]->paint()); $this->assertWantedPattern(‘/invalid/i’, $form[1]->paint()); $this->assertNoUnwantedPattern(‘/invalid/i’, $form[2]->paint()); } }
这个测试捕获(包含)了所有的基本方面:建立一个Post实例的存根,使用它建立一个组件集合,然后将集合传送给validate方法。
class FormHandler { function validate(&$form, &$post) { // first name required if (!strlen($post->get(‘fname’))) { $form[0] =& new Invalid($form[0]); } 212 The Decorator Pattern // last name required if (!strlen($post->get(‘lname’))) { $form[1] =& new Invalid($form[1]); } } }
不协调的代码
当我看这段代码时,我发现了两个不协调之处:通过数字索引访问表单元素,需要传递$_post数组。给validation方法。在以后的重构中,最好是创建一个组件集合用一个以表单元素名字索引的关联数组表示或者用一个Registry模式作为更合理的一步。你也可以给类Widget增加一个方法返回它的
当前数值,取消需要传递$_Post实例给Widget集合的构造函数。所有这些都超出了这个例子目的的范围。
为了验证目的,我们继续增加一个简单的 正则方法(regex)来验证email地址:
class FormHandlerTestCase extends UnitTestCase { // ... function testValidateBadEmail() { $post =& new Post; $post->set(‘fname’, ‘Jason’); $post->set(‘lname’, ‘Sweat’); $post->set(‘email’, ‘jsweat_php AT yahoo DOT com’); $form = FormHandler::build($post); $this->assertFalse(FormHandler::validate($form, $post)); $this->assertNoUnwantedPattern(‘/invalid/i’, $form[0]->paint()); $this->assertNoUnwantedPattern(‘/invalid/i’, $form[1]->paint()); $this->assertWantedPattern(‘/invalid/i’, $form[2]->paint()); } }
实现这个简单的email验证的代码如下:
class FormHandler { function validate(&$form, &$post) { // first name required if (!strlen($post->get(‘fname’))) { $form[0] =& new Invalid($form[0]); } // last name required if (!strlen($post->get(‘lname’))) { $form[1] =& new Invalid($form[1]); } // email has to look real if (!preg_match(‘~\w+@(\w+\.)+\w+~’ ,$post->get(‘email’))) { $form[2] =& new Invalid($form[2]); } } }
出处:phpchina
责任编辑:bluehearts
上一页 php设计模式介绍之装饰器模式 [4] 下一页 php设计模式介绍之装饰器模式 [6]
◎进入论坛网络编程版块参加讨论
|