php教程:php设计模式介绍之迭代器模式(4)

http://www.itjxue.com  2015-07-17 08:20  来源:未知  点击次数: 

不同的迭代器 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 循环迭代器。

(责任编辑:IT教学网)

更多