后,表单渲染 出来如下图所示:
为建立统一的API,我们创建一个基本的组件类(如果这是php5的例子,这或许会使用接口) 。既然所有的组件(表单元素)都必须渲染一些输出,组建类可以仅仅只有一个paint()方法。
class Widget {
function paint() {
return $this->_asHtml();
}
}
让我们以一个基本的text输入组件开始。它(组件)必须要包含输入区域的 名字(name)而且输入内容可以以HTML的方式渲染。
class TextInput extends Widget {
var $name;
var $value;
function TextInput($name, $value=’’) {
$this->name = $name;
$this->value = $value;
}
function _asHtml () {
return ‘<input type=”text” name=”’.$this- >name.’” value=”’
.$this- >value.’”>’;
}
}
一个基本的测试可以验证HTML 代码是否正确——作为参数传入给构造函数的名字,值(内容)是否传递到渲染后的输出中 :
class WidgetTestCase extends UnitTestCase {
function testTextInput() {
$text =& new TextInput(‘foo’, ‘bar’);
$output = $text->paint();
$this->assertWantedPattern(
‘~^<input type=”text”[^>]*>$~i’, $output);
$this- >assertWantedPattern(‘~name=”foo”~i’, $output);
$this- >assertWantedPattern(‘~value=”bar”~i’, $output);
}
}
TextInput组件工作正常,但是它的用户接口非常糟糕,它缺少友好的描述,如 “First Name” 或者 “Email Address.” 。因此,下一个增加到组件类的合理 的特性就是一个描述。我们进入有能够统一增加(一些特性)能力的装饰器模式。
作为开始,我 们建立一个普通的可以被扩展产生具体的特定装饰器的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 UnitTestCa
|