PHP设计模式(八)装饰器模式Decorator实例详解【(5)

以创建一个php脚本使用FormHandler类来产生HTML表单:

<form action=”formpage.php” method=”post”>
<?php
$post =& Post::autoFill();
$form = FormHandler::build($post);
foreach($form as $widget) {
 echo $widget->paint(), "<br>\n";
}
?>
<input type=”submit” value=”Submit”>
</form>

现在,你已经拥有了个提交给它自身并且能保持posted数据的表单处理(form handler) 类。
现在。我们继续为表单添加一些验证机制。方法是编辑另一个组件装饰器类来表达一个“invalid”状态并扩展FormHandler类增加一个validate()方法以处理组件示例数组。如果组件非法(“invalid”),我们通过一个“invalid”类将它包装在<span>元素中。

<?php
class Invalid extends WidgetDecorator {
 
 function paint() {
 return '<span class="invalid">'.$this->widget->paint().'</span>';
 }
}

FormHandler新加方法validate:

/**
 * 实现
 *
 */
class FormHandler {
 function build(&$post) {
 return array(
 new ConcreteDecoratorLabeled('First Name', new ConcreteComponentTextInput('fname', $post->get('fname')))
 ,new ConcreteDecoratorLabeled('Last Name', new ConcreteComponentTextInput('lname', $post->get('lname')))
 ,new ConcreteDecoratorLabeled('Email', new ConcreteComponentTextInput('email', $post->get('email')))
 );
 
 }
 
 function validate(&$form, &$post) {
 $valid = true;
 // first name required
 if (!strlen($post->get('fname'))) {
  $form[0] =& new Invalid($form[0]);
  $valid = false;
 }
 
 // last name required
 if (!strlen($post->get('lname'))) {
  $form[1] =& new Invalid($form[1]);
  $valid = false;}
  // email has to look real
  if (!preg_match('~\w+@(\w+\.)+\w+~'
  ,$post->get('email'))) {
  $form[2] =& new Invalid($form[2]);
  $valid = false;
  }
  return $valid;
 
 }
}

最后结果:

<html>
<head>
<title>Decorator Example</title>
<style type="text/css">
.invalid {color: red; }
.invalid input { background-color: red; color: yellow; }
#myform input { position: absolute; left: 110px; width: 250px;  font-weight: bold;}
</style>
</head>
<body>
<form action="<?php echo $_SERVER["PHP_SELF"]; ?>" method="post">
<div id="myform">
<?php 
$pos =& Post::autoFill();
$form = FormHandler::build($post);
if ($_POST) { FormHandler::validate($form, $post);
}
foreach($form as $widget) {
 echo $widget->paint(), "<br>\n";
}
?>
 
</div>
<input type="submit" value="Submit">
</form>
</body>
</html>

9. 装饰器模式与其他相关模式

1)Adapter 模式:Decorator模式不同于Adapter模式,因为装饰仅改变对象的职责而