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

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

过滤迭代器

利用迭代器,你不仅仅可以显示集合中的每一项。你还可以选择显示的项。修改 Library::getIterator() 来使用其它两种迭代器类型。

class  Library  {
//  ...
function  getIterator($type=false)  {
switch  (strtolower($type))  {
case  ‘media’:
$iterator_class  =  ‘LibraryIterator’;
break;
case  ‘available’:
$iterator_class  =  ‘LibraryAvailableIterator’;
break;
case  ‘released’:
$iterator_class  =  ‘LibraryReleasedIterator’;
break;
default:
$iterator_class  =  ‘LibraryGofIterator’;
}
return  new  $iterator_class($this->collection);
}
}

类 LibraryAvailableIterator 仅可以迭代状态为“library”的项”(重新调用 checkOut() 方法,将状态更改为“borrowed”)。

class  IteratorTestCase  extends  UnitTestCase  {
//  ...
function  TestAvailableIteratorUsage()  {
$this->lib->add($dvd  =  new  Media(‘test’,  1999));
$this->lib->add(new  Media(‘name4’,  1999));
$this->assertIsA(
$it  =  $this->lib->getIterator(‘available’)
,’LibraryAvailableIterator’);
$output  = ‘’;
while  ($item  =  $it->next())  {
$output  .=  $item->name;
}
$this->assertEqual(‘name1name2name3testname4’,  $output);
$dvd->checkOut(‘Jason’);
$it  =  $this->lib->getIterator(‘available’);
$output  = ‘’;
while  ($item  =  $it->next())  {
$output  .=  $item->name;
}
$this->assertEqual(‘name1name2name3name4’,  $output);
}
}

该测试创建一个新的介质实例,并将其存储在变量 $dvd 中。突出显示第一个 assertEqual() 声明验证利用 LibraryAvailableIterator 进行迭代时,存在一个新的项。接下来,测试使用 checkOut() 方法,并验证新的项已丢失,不显示。实现过滤得代码非常类似于 LibraryIterator::next(),差别在于在返回项之前执行过滤。如果当前项与过滤条件不匹配,则代码返回 $this->next()。

class  LibraryAvailableIterator  {
protected  $collection  =  array();
protected  $first=true;
function  __construct($collection)  {
$this->collection  =  $collection;
}
function  next()  {
if  ($this->first)  {
$this->first  =  false;
$ret  =  current($this->collection);
}  else  {
$ret  =  next($this->collection);
}
if  ($ret  &&  ‘library’  !=  $ret->status)  {
return  $this->next();
}
return  $ret;
}
}

(责任编辑:IT教学网)

更多