LibraryGofIterator 接收了構(gòu)造函數(shù)中的 $collection, 這一點(diǎn)非常重要(參見(jiàn)上面的 Library 最小化實(shí)現(xiàn))并從 currentItem() 方法返回 current() 項(xiàng)。
class LibraryGofIterator { protected $collection; function __construct($collection) { $this->collection = $collection; } function currentItem() { return current($this->collection); } function isDone() { return false; } }
在下一個(gè)迭代會(huì)出現(xiàn)什么? next() 方法應(yīng)該更改currentItem() 方法返回的項(xiàng)。下面的測(cè)試捕獲了所期望的行為:
class IteratorTestCase extends UnitTestCase { function setup() { /* ... */ } function TestGetGofIterator() { $this->assertIsA($it = $this->lib->getIterator(), ‘LibraryGofIterator’); $this->assertFalse($it->isdone()); $this->assertIsA($first = $it->currentItem(), ‘Media’); $this->assertEqual(‘name1’, $first->name); $this->assertFalse($it->isdone()); $this->assertTrue($it->next()); $this->assertIsA($second = $it->currentItem(), ‘Media’); $this->assertEqual(‘name2’, $second->name); $this->assertFalse($it->isdone()); } }
重新建立在 PHP 的數(shù)組函數(shù)之上,在數(shù)組上使用 next():
class LibraryGofIterator { protected $collection; function __construct($collection) { $this->collection = $collection; } function currentItem() { return current($this->collection); } function next() { return next($this->collection); } function isDone() { return false; } }
除了 isDone() 方法必須返回 之外,第三個(gè)迭代看起來(lái)很像其他的迭代。你還希望 next() 能夠成功移到下一個(gè)迭代:
class IteratorTestCase extends UnitTestCase { function setup() { /* ... */ } function TestGetGofIterator() { $this->assertIsA($it = $this->lib->getIterator(), ‘LibraryGofIterator’); $this->assertFalse($it->isdone()); $this->assertIsA($first = $it->currentItem(), ‘Media’); $this->assertEqual(‘name1’, $first->name); $this->assertFalse($it->isdone()); $this->assertTrue($it->next()); $this->assertIsA($second = $it->currentItem(), ‘Media’); $this->assertEqual(‘name2’, $second->name); $this->assertFalse($it->isdone()); $this->assertTrue($it->next()); $this->assertIsA($third = $it->currentItem(), ‘Media’); $this->assertEqual(‘name3’, $third->name); $this->assertFalse($it->next()); $this->assertTrue($it->isdone()); } }
對(duì) next() 和 isDone() 方法稍加修改,所有的測(cè)試都通過(guò)了。代碼如下:
class LibraryGofIterator { protected $collection; function __construct($collection) { $this->collection = $collection; } function first() { reset($this->collection); } function next() { return (false !== next($this->collection)); } function isDone() { return (false === current($this->collection)); } function currentItem() { return current($this->collection); } }
迭代器測(cè)試用例只存在一個(gè)問(wèn)題:它沒(méi)有反映迭代器的典型用法。是的,它測(cè)試了迭代器模式的所有功能,但應(yīng)用程序需要采用更簡(jiǎn)單的方法來(lái)使用迭代器。因此,下一步是使用更貼實(shí)際的代碼來(lái)編寫(xiě)測(cè)試。
class IteratorTestCase extends UnitTestCase { protected $lib; function setup() { /* ... */ } function TestGetGofIterator() { /* ... */ } function TestGofIteratorUsage() { $output = ‘’; for ($it=$this->lib->getIterator(); !$it->isDone(); $it->next()){ $output .= $it->currentItem()->name; } $this->assertEqual(‘name1name2name3’, $output); } }
目前,迭代器的實(shí)現(xiàn)復(fù)制了某個(gè)數(shù)組(集合),并使用 PHP 的內(nèi)部指針來(lái)跟蹤迭代。你還可以通過(guò)自己跟蹤集合索引來(lái)實(shí)現(xiàn)迭代器。這需要 Library 中的一種新的 accessor 方法來(lái)通過(guò)關(guān)鍵字訪(fǎng)問(wèn)對(duì)象。
class Library { // ... function get($key) { if (array_key_exists($key, $this->collection)) { return $this->collection[$key]; } } }
同樣,在 Library::getIterator() 方法中,你可能將 $this(library 本身)傳遞給構(gòu)造程序,而不是將 $this 傳遞給集合(數(shù)組包含Media 集合)。外部的迭代器然后只是內(nèi)部地跟蹤指針以了解它當(dāng)前引用的是哪一個(gè) Library 集合元素,并將使用構(gòu)造行數(shù)中從引用到 Library 的傳遞來(lái)檢索當(dāng)前的對(duì)象。
class LibraryGofExternalIterator { protected $key = 0; protected $collection; function __construct($collection) { $this->collection = $collection; } function first() { $this->key=0; } function next() { return (++$this->key < $this->collection->count()); } function isDone() { return ($this->key >= $this->collection->count()); } function currentItem() { return $this->collection->get($this->key); } }
這一實(shí)現(xiàn)假設(shè)你的集合數(shù)組從 0 開(kāi)始建立索引,并且是完全連續(xù)的。
出處:phpchina
責(zé)任編輯:bluehearts
上一頁(yè) php設(shè)計(jì)模式介紹之迭代器模式 [2] 下一頁(yè) php設(shè)計(jì)模式介紹之迭代器模式 [4]
◎進(jìn)入論壇網(wǎng)絡(luò)編程版塊參加討論
|