作为开始
,我们建立一个普通的可以被扩展产生具体的特定装饰器的WidgetDecorator类
。至少WidgetDecorator类应该能够在它的构造函数中接受一个组件
,并复制公共方法paint()
。 classWidgetDecorator{
var$widget;
TheDecoratorPattern207
functionWidgetDecorator(&$widget){
$this->widget=&$widget;
}
functionpaint(){
return$this->widget->paint();
}
}
为建立一个标签(lable),需要传入lable的内容,以及原始的组件:
classLabeledextendsWidgetDecorator{
var$label;
functionLabeled($label,&$widget){
$this->label=$label;
$this->WidgetDecorator($widget);
}
}
有标签的组件也需要复制paint()方法,并将标签信息增加到输出中:
classLabeledextendsWidgetDecorator{
var$label;
functionLabeled($label,&$widget){
$this->label=$label;
$this->WidgetDecorator($widget);
}
functionpaint(){
return‘<b>’.$this->label.’:</b>‘.$this->widget->paint();
}
}
你可以用一个测试检验它:
classWidgetTestCaseextendsUnitTestCase{
functiontestLabeled(){
$text=&newLabeled(
‘Email’
,newTextInput(‘email’));
$output=$text->paint();
208TheDecoratorPattern
$this->assertWantedPattern(‘~^<b>Email:</b><input~i’,$output);
}
}
我们已经看到TextInput和Labeled类的能力,你可以装配一个类整体来管理表单(form)。
FormHandler类有一个静态的build()方法从表单的各种元素创建一个部件的数组。
classFormHandlerTestCaseextendsUnitTestCase{
functiontestBuild(){
$this->assertIsA($form=FormHandler::build(newPost),‘Array’);
$this->assertEqual(3,count($form));
$this->assertIsA($form[1],‘Labeled’);
$this->assertWantedPattern(‘~email~i’,$form[2]->paint());
}
}
实现FormHandler的代码:
classFormHandler{
functionbuild(){
returnarray(
newLabeled(‘FirstName’,newTextInput(‘fname’))
,newLabeled(‘LastName’,newTextInput(‘lname’))
,newLabeled(‘Email’,newTextInput(‘email’))
);
}
}
现在,这段代码并不能工作—没有通过$_post提交的数据。因为这段代码必须要使用一个MockObject对象(参见第6章)测试,现在我们可以将$_post数据包装在一个类似哈希的对象中—与Registry(参见第五章)类似,或者模仿WACT的DataSource从Specificationpattern
classPost{
var$store=array();
functionget($key){
if(array_key_exists($key,$this->store))
return$this->store[$key];
TheDecoratorPattern209
}
functionset($key,$val){
$this->store[$key]=$val;
}
}