不同的迭代器 API
雖然前面的代碼是 GoF 所述迭代器模式的完整實現(xiàn),你還可能會發(fā)現(xiàn)四種方法的 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); } }
在上述代碼中,注意簡化的循環(huán)控制結(jié)構(gòu)。 next() 返回對象或者false,允許你在 while 循環(huán)條件中執(zhí)行分配。下面的一些示例檢驗使用較小接口的不同迭代器模式。為了方便,將 Library::getIterator() 方法更改為參數(shù)化的 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() 現(xiàn)在接受一個參數(shù)以選擇返回什么樣的迭代器。缺省為 LibraryGofIterator(因此現(xiàn)有的測試仍然能夠通過)。將字符串媒體傳遞給所創(chuàng)建的方法,并返回 LibraryIterator。這是一些實現(xiàn) LibraryIterator 的代碼:
class LibraryIterator { protected $collection; function __construct($collection) { $this->collection = $collection; } function next() { return next($this->collection); } }
請注意調(diào)試結(jié)果的紅色標記!什么導致發(fā)生錯誤“Equal expectation fails at character 4 with name1name2name3 and name2name3”?不知何故,跳過了第一次迭代 - 這是 bug。要修訂該錯誤,對于 next() 方法的第一次調(diào)用,返回 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 循環(huán)迭代器。
出處:phpchina
責任編輯:bluehearts
上一頁 php設計模式介紹之迭代器模式 [3] 下一頁 php設計模式介紹之迭代器模式 [5]
◎進入論壇網(wǎng)絡編程版塊參加討論
|