测试类
现在,代码更加复杂了,但是其如何支持其它迭代器类型?添加一个关于“发行版”迭代器的测试,来查看这种设计的其它迭代器如何工作。
class PolySplIteratorTestCase extends UnitTestCase { // ... function TestReleasedForeach() { $this->lib->add(new Media(‘second’, 1999)); $this->lib->add(new Media(‘first’, 1989)); $output = array(); $this->lib->iteratorType(‘Released’); foreach($this->lib as $item) { $output[] = $item->name .’-’. $item->year; } $this->assertEqual( ‘first-1989 second-1999 name1-2000 name3-2001 name2-2002’ ,implode(‘ ‘,$output)); } }
上面的测试用例看起来也很熟悉,因为其非常类似于前一个“发行版”迭代器,但是使用了 foreach 控制结构进行循环。
class PolymorphicForeachableLibrary extends Library implements Iterator { protected $iterator_type; protected $iterator; function __construct() { $this->iteratorType(); } function iteratorType($type=false) { switch(strtolower($type)) { case ‘released’: $this->iterator_type = ‘ReleasedLibraryIterator’; break; default: $this->iterator_type = ‘StandardLibraryIterator’; } $this->rewind(); } // ... function rewind() { $type = $this->iterator_type; $this->iterator = new $type($this->collection); $this->iterator->rewind(); } }
新的 iteratorType() 方法使你转变要使用的迭代器的类型。(因为迭代器类型并不是在对象安装期间选中的,并且你可以在空闲时再次调用 iteratorType() 方法来选择不同迭代器类型,所以实际上是在 State 模式执行代码,而不是 Strategy 模式。)
class ReleasedLibraryIterator extends StandardLibraryIterator { function __construct($collection) { usort($collection ,create_function(‘$a,$b’,’return ($a->year - $b->year);’)); $this->collection = $collection; } }
你可以简单地通过扩展 StandardLibraryIterator 并覆盖构造函数来添加入局数组的排序,从而实现 ReleasedLibraryIterator。并且,通过它,你可以有一个 working PolymorphicForeachableLibrary。
总结
迭代器是标准化地地处理应用程序中对象集合的方法。这些例子是基于数组的,但是对于拥有同一个接口的非数组集合,工作起来将更加强大。使用 foreach 控制结构方式的集合确实非常酷。 SPL 实现中最不幸的问题是与迭代器可能存在的名称空间冲突。有多少 PHP4 面向对象的代码拥有类似于迭代器类作为库迭代器类的基类?在一些容量中有多少 5 种必需方法的定义?可能一个更加具有深刻含义的名称就能实现 Foreachable。如果你选择使用 SPL,则还应该研究其它支持的迭代器,例如RecursiveArrayIterator 和其它众多迭代器。
下文:《PHP设计模式介绍》第九章 观测模式
本文链接:http://www.blueidea.com/tech/program/2008/6012.asp
出处:phpchina
责任编辑:bluehearts
上一页 php设计模式介绍之迭代器模式 [7] 下一页
◎进入论坛网络编程版块参加讨论
|