日韩天天综合网_野战两个奶头被亲到高潮_亚洲日韩欧美精品综合_av女人天堂污污污_视频一区**字幕无弹窗_国产亚洲欧美小视频_国内性爱精品在线免费视频_国产一级电影在线播放_日韩欧美内地福利_亚洲一二三不卡片区

《PHP設(shè)計(jì)模式介紹》第八章 迭代器模式(2)_PHP教程

編輯Tag賺U幣
教程Tag:暫無(wú)Tag,歡迎添加,賺取U幣!

推薦:《PHP設(shè)計(jì)模式介紹》第七章 策略模式
在編寫(xiě)面向?qū)ο蟮拇a的時(shí),有些時(shí)候你需要一個(gè)能夠自己根據(jù)不同的條件來(lái)引入不同的操作對(duì)象實(shí)例。例如,一個(gè)菜單功能能夠根據(jù)用戶(hù)的“皮膚”首選項(xiàng)來(lái)決定是否采用水平的還是垂直的排


你的集合類(lèi)必須提供 Factory(參見(jiàn)第 3 章)來(lái)創(chuàng)建迭代器的實(shí)例。

迭代器類(lèi)定義 first() 轉(zhuǎn)到集合開(kāi)始的接口,

next() 移到序列中的下一個(gè)項(xiàng)作為你的循環(huán),currentItem() 從集合檢索當(dāng)前的項(xiàng)作為你的循環(huán), isDone() 用于指出你在整個(gè)集合中循環(huán)結(jié)束的時(shí)間。

在“示例代碼”部分,LibraryGofIterator 類(lèi)是一個(gè)直接實(shí)現(xiàn) GoF 迭代器設(shè)計(jì)模式的示例。


樣本代碼

在 Library 內(nèi)實(shí)現(xiàn) GoF 迭代器模式的第一步是為新的具體迭代器寫(xiě)一個(gè)新的測(cè)試用例。因?yàn)槊恳环N測(cè)試方法都將操縱包含 Media 實(shí)例的 Library,你可以清空 UnitTestCase::setUp() 方法,從而在每種測(cè)試的已知狀態(tài)下將變量填充到 Library 中。

首先,將 Library::getIterator() 方法作為L(zhǎng)ibraryGofIterator 類(lèi)的 一個(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)滿(mǎn)足你的測(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());
}
}


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è)試。

分享:《PHP設(shè)計(jì)模式介紹》第六章 偽對(duì)象模式
面向?qū)ο蟮木幊讨载S富多彩,部分是由于對(duì)象間的相互聯(lián)系與作用。一個(gè)單一的對(duì)象就能封裝一個(gè)復(fù)雜的子系統(tǒng),使那些很復(fù)雜的操作能夠通過(guò)一些方法的調(diào)用而簡(jiǎn)化。(無(wú)所不在的數(shù)據(jù)庫(kù)連接就是這

來(lái)源:模板無(wú)憂(yōu)//所屬分類(lèi):PHP教程/更新時(shí)間:2008-08-22
相關(guān)PHP教程