作为开始,我们建立一个普通的可以被扩展产生具体的特定装饰器的WidgetDecorator类。至少WidgetDecorator类应该能够在它的构造函数中接受一个组件,并复制公共方法paint()。
class WidgetDecorator { var $widget; The Decorator Pattern 207 function WidgetDecorator(&$widget) { $this->widget =& $widget; } function paint() { return $this->widget->paint(); } }
为建立一个标签(lable),需要传入lable的内容,以及原始的组件:
class Labeled extends WidgetDecorator { var $label; function Labeled($label, &$widget) { $this->label = $label; $this->WidgetDecorator($widget); } }
有标签的组件也需要复制paint()方法,并将标签信息增加到输出中:
class Labeled extends WidgetDecorator { var $label; function Labeled($label, &$widget) { $this->label = $label; $this->WidgetDecorator($widget); } function paint() { return ‘<b>’.$this->label.’:</b> ‘.$this->widget->paint(); } }
你可以用一个测试检验它:
class WidgetTestCase extends UnitTestCase { function testLabeled() { $text =& new Labeled( ‘Email’ ,new TextInput(‘email’)); $output = $text->paint(); 208 The Decorator Pattern $this->assertWantedPattern(‘~^<b>Email:</b> <input~i’, $output); } }
我们已经看到TextInput和Labeled类的能力,你可以装配一个类整体来管理表单(form)。 FormHandler类有一个静态的build()方法从表单的各种元素创建一个部件的数组。
class FormHandlerTestCase extends UnitTestCase { function testBuild() { $this->assertIsA($form = FormHandler::build(new Post), ‘Array’); $this->assertEqual(3, count($form)); $this->assertIsA($form[1], ‘Labeled’); $this->assertWantedPattern(‘~email~i’, $form[2]->paint()); } }
实现FormHandler 的代码:
class FormHandler { function build() { return array( new Labeled(‘First Name’, new TextInput(‘fname’)) ,new Labeled(‘Last Name’, new TextInput(‘lname’)) ,new Labeled(‘Email’, new TextInput(‘email’)) ); } }
现在,这段代码并不能工作—没有通过$_post提交的数据。因为这段代码必须要使用一个MockObject对象 (参见第6章)测试,现在我们可以将$_post数据包装在一个类似哈希的对象中—与Registry(参见第五章)类似,或者模仿WACT的DataSource从Specification pattern
class Post { var $store = array(); function get($key) { if (array_key_exists($key, $this->store)) return $this->store[$key]; The Decorator Pattern 209 } function set($key, $val) { $this->store[$key] = $val; } }
出处:phpchina
责任编辑:bluehearts
上一页 php设计模式介绍之装饰器模式 [2] 下一页 php设计模式介绍之装饰器模式 [4]
◎进入论坛网络编程版块参加讨论
|