《PHP设计模式介绍》第十二章 装饰器模式(3)_PHP教程
推荐:《PHP设计模式介绍》第十一章 代理模式因为某个对象消耗太多资源,而且你的代码并不是每个逻辑路径都需要此对象, 你曾有过延迟创建对象的想法吗 ( if和else就是不同的两条逻辑路径) ? 你有想过限制访问某个对象,也就是说,提供一组方法
作为开始,我们建立一个普通的可以被扩展产生具体的特定装饰器的WidgetDecorator类。至少WidgetDecorator类应该能够在它的构造函数中接受一个组件,并复制公共方法paint。
class WidgetDecorator { var $widget; 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]; } function set($key, $val) { $this->store[$key] = $val; } } |
想更方便的话,你可以使用Factory模式或者自动填充的方法来从$_POST里面提取关键字。
class Post { // ... function &autoFill() { $ret =& new Post; foreach($_POST as $key => $value) { $ret->set($key, $value); } return $ret; } } |
使用这个Post类,你可以编辑你的FormHandler::build() 方法,默认使用已经存在的$_post数据:
class FormHandler { function build(&$post) { return array( new Labeled(‘First Name’ , new TextInput(‘fname’, $post->get(‘fname’))) ,new Labeled(‘Last Name’ , new TextInput(‘lname’, $post->get(‘lname’))) ,new Labeled(‘Email’ , new TextInput(‘email’, $post->get(‘email’))) ); } } |
现在你可以创建一个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) 类。
分享:《PHP设计模式介绍》第十章 规范模式在一个应用软件的成型过程中,一些意想不到的商业逻辑到处出现。比如,基于价格的考虑,这个任务必须减少项目;而那个任务也因为销售税而必须选择合适的比率;而其它的任务也必须因为其他的特别
- 相关链接:
- 教程说明:
PHP教程-《PHP设计模式介绍》第十二章 装饰器模式(3)。