我們回到本章的重點(diǎn),迭代器設(shè)計(jì)模式的實(shí)現(xiàn)。下列 UML 類圖顯示了 GoF 迭代器模式與 Media 和 Library 類結(jié)合使用鞏固示例的方法。
? 你的集合類必須提供 Factory(參見第 3 章)來(lái)創(chuàng)建迭代器的實(shí)例。 ? 迭代器類定義 first() 轉(zhuǎn)到集合開始的接口,
next() 移到序列中的下一個(gè)項(xiàng)作為你的循環(huán),currentItem() 從集合檢索當(dāng)前的項(xiàng)作為你的循環(huán), isDone() 用于指出你在整個(gè)集合中循環(huán)結(jié)束的時(shí)間。
在“示例代碼”部分,LibraryGofIterator 類是一個(gè)直接實(shí)現(xiàn) GoF 迭代器設(shè)計(jì)模式的示例。
樣本代碼
在 Library 內(nèi)實(shí)現(xiàn) GoF 迭代器模式的第一步是為新的具體迭代器寫一個(gè)新的測(cè)試用例。因?yàn)槊恳环N測(cè)試方法都將操縱包含 Media 實(shí)例的 Library,你可以清空 UnitTestCase::setUp() 方法,從而在每種測(cè)試的已知狀態(tài)下將變量填充到 Library 中。
首先,將 Library::getIterator() 方法作為L(zhǎng)ibraryGofIterator 類的 一個(gè) Factory 實(shí)例。
class IteratorTestCase extends UnitTestCase { protected $lib; function setup() { $this->lib = new Library; $this->lib->add(new Media(‘name1’, 2000)); $this->lib->add(new Media(‘name2’, 2002)); $this->lib->add(new Media(‘name3’, 2001)); }
function TestGetGofIterator() { $this->assertIsA($it = $this->lib->getIterator() ,’LibraryGofIterator’); } }
實(shí)現(xiàn):
class Library { // ... function getIterator() { return new LibraryGofIterator($this->collection); } }
getIterator() 方法將 Library 的 $collection 傳遞給新的具體迭代器結(jié)構(gòu)。這一方法有兩個(gè)重要的實(shí)現(xiàn):每個(gè)迭代器都是獨(dú)立的,因此可以同時(shí)操作多個(gè)迭代器。另外,迭代器在數(shù)組上的操作是當(dāng)?shù)鞅徽?qǐng)求時(shí)才執(zhí)行的。如果之后將另一個(gè)項(xiàng)添加到集合中,你必須請(qǐng)求另一個(gè)迭代器來(lái)顯示它(至少是在該實(shí)現(xiàn)中)。讓我們通過(guò)將聲明添加到 TestGetGofIterator() 方法以匹配迭代器設(shè)計(jì)模式,繼續(xù)對(duì)測(cè)試進(jìn)行加強(qiáng)。
如果你已經(jīng)對(duì)整個(gè)集合進(jìn)行遍歷,則 isDone() 方法只應(yīng)該為 true。如果 iterator 剛剛創(chuàng)建,則 isDone() 顯然返回 false,從而指出集合可以遍歷。
class IteratorTestCase extends UnitTestCase { function setup() { /* ... */ } function TestGetGofIterator() { $this->assertIsA($it = $this->lib->getIterator() ,’LibraryGofIterator’); $this->assertFalse($it->isdone()); } }
與 TDD 一樣,盡可能實(shí)現(xiàn)最簡(jiǎn)單的代碼來(lái)滿足你的測(cè)試用例:
class LibraryGofIterator { function isDone() { return false; } }
因此,在第一個(gè)迭代器間,應(yīng)該發(fā)生什么呢? currentItem() 應(yīng)該返回第一個(gè) Media 對(duì)象,這個(gè)對(duì)象是在 IteratorTestCase::setUp() 方法中添加的,isDone() 應(yīng)該繼續(xù)為 false,因?yàn)榱韮蓚(gè)項(xiàng)仍然等待遍歷。
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()); } }
出處:phpchina
責(zé)任編輯:bluehearts
上一頁(yè) php設(shè)計(jì)模式介紹之迭代器模式 [1] 下一頁(yè) php設(shè)計(jì)模式介紹之迭代器模式 [3]
◎進(jìn)入論壇網(wǎng)絡(luò)編程版塊參加討論
|