不同的迭代器 API
虽然前面的代码是 GoF 所述迭代器模式的完整实现,你还可能会发现四种方法的 API 有一点臃肿。如果是,你可以将 collapse next(), currentItem(), 和 isDone() 都并入 next() 中,用来从集合中返回本项或下一项,或者如果整个集合被遍历过了,则返回 false。这是一个测试不同 API 的代码:
class IteratorTestCase extends UnitTestCase { // ... function TestMediaIteratorUsage() { $this->assertIsA( $it = $this->lib->getIterator(‘media’) ,’LibraryIterator’); $output = ‘’; while ($item = $it->next()) { $output .= $item->name; } $this->assertEqual(‘name1name2name3’, $output); } }
在上述代码中,注意简化的循环控制结构。 next() 返回对象或者false,允许你在 while 循环条件中执行分配。下面的一些示例检验使用较小接口的不同迭代器模式。为了方便,将 Library::getIterator() 方法更改为参数化的 Factory,以便你可以从单一方法中获取四种的方法迭代器或两种方法的迭代器(next() 和 reset())。
class Library { // ... function getIterator($type=false) { switch (strtolower($type)) { case ‘media’: $iterator_class = ‘LibraryIterator’; break; default: $iterator_class = ‘LibraryGofIterator’; } return new $iterator_class($this->collection); } }
这里面的 Library::getIterator() 现在接受一个参数以选择返回什么样的迭代器。缺省为 LibraryGofIterator(因此现有的测试仍然能够通过)。将字符串媒体传递给所创建的方法,并返回 LibraryIterator。这是一些实现 LibraryIterator 的代码:
class LibraryIterator { protected $collection; function __construct($collection) { $this->collection = $collection; } function next() { return next($this->collection); } }
请注意调试结果的红色标记!什么导致发生错误“Equal expectation fails at character 4 with name1name2name3 and name2name3”?不知何故,跳过了第一次迭代 - 这是 bug。要修订该错误,对于 next() 方法的第一次调用,返回 current()。
class LibraryIterator { protected $collection; protected $first=true; function __construct($collection) { $this->collection = $collection; } function next() { if ($this->first) { $this->first = false; return current($this->collection); } return next($this->collection); } }
Presto! 绿色条和改进的 while 循环迭代器。
出处:phpchina
责任编辑:bluehearts
上一页 php设计模式介绍之迭代器模式 [3] 下一页 php设计模式介绍之迭代器模式 [5]
◎进入论坛网络编程版块参加讨论
|