PHP設(shè)計(jì)模式之迭代器(Iterator)模式入門(mén)與應(yīng)用詳解
本文實(shí)例講述了PHP設(shè)計(jì)模式之迭代器(Iterator)模式。分享給大家供大家參考,具體如下:
迭代器有時(shí)又稱光標(biāo)(cursor)是程式設(shè)計(jì)的軟件設(shè)計(jì)模式,可在容器物件(container,例如list或vector)上遍訪的接口,設(shè)計(jì)人員無(wú)需關(guān)心容器物件的內(nèi)容,現(xiàn)在呢,各種語(yǔ)言實(shí)作Iterator的方式皆不盡同,有些面向?qū)ο笳Z(yǔ)言像Java, C#, Python, Delphi都已將Iterator的特性內(nèi)建語(yǔ)言當(dāng)中,完美的跟語(yǔ)言整合,我們稱之隱式迭代器(implicit iterator),但像是C++語(yǔ)言本身就沒(méi)有Iterator的特色,但STL仍利用template實(shí)作了功能強(qiáng)大的iterator。
但是,PHP5開(kāi)始支持了接口, 并且內(nèi)置了Iterator接口, 所以如果你定義了一個(gè)類,并實(shí)現(xiàn)了Iterator接口,那么你的這個(gè)類對(duì)象就是ZEND_ITER_OBJECT,否則就是ZEND_ITER_PLAIN_OBJECT。對(duì)于ZEND_ITER_PLAIN_OBJECT的類,foreach會(huì)通過(guò)HASH_OF獲取該對(duì)象的默認(rèn)屬性數(shù)組,然后對(duì)該數(shù)組進(jìn)行foreach,而對(duì)于ZEND_ITER_OBJECT的類對(duì)象,則會(huì)通過(guò)調(diào)用對(duì)象實(shí)現(xiàn)的Iterator接口相關(guān)函數(shù)來(lái)進(jìn)行foreach。
咱們什么也別說(shuō),先來(lái)看下迭代器的定義,那就是提供一種方法順序訪問(wèn)一個(gè)聚合對(duì)象中各個(gè)元素,而又不暴露該對(duì)象的內(nèi)部顯示。它可幫助構(gòu)造特定的對(duì)象,那些對(duì)象能夠提供單一標(biāo)準(zhǔn)接口循環(huán)或迭代任何類型的可計(jì)數(shù)數(shù)據(jù)。來(lái)看下迭代器模式的結(jié)構(gòu)圖:
咋樣,反正我現(xiàn)在是一頭霧水。。。
再來(lái)看下迭代器需要用到的內(nèi)部方法:
- Iterator::current — Return the current element 返回當(dāng)前元素
- Iterator::key — Return the key of the current element 返回當(dāng)前元素的鍵
- Iterator::next — Move forward to next element 移向下一個(gè)元素
- Iterator::rewind — Rewind the Iterator to the first element 重新回到第一個(gè)元素
- Iterator::valid — Checks if current position is valid 檢查當(dāng)前位置的有效性
咱不廢話哈,直接來(lái)看下網(wǎng)上比較經(jīng)典的一個(gè)實(shí)例:
class MyIterator implements Iterator
{
private $var = array();
public function __construct($array)
{
if (is_array($array)) {
$this->var = $array;
}
}
public function rewind() {
echo "倒回第一個(gè)元素\n";
reset($this->var);
}
public function current() {
$var = current($this->var);
echo "當(dāng)前元素: $var\n";
return $var;
}
public function key() {
$var = key($this->var);
echo "當(dāng)前元素的鍵: $var\n";
return $var;
}
public function next() {
$var = next($this->var);
echo "移向下一個(gè)元素: $var\n";
return $var;
}
public function valid() {
$var = $this->current() !== false;
echo "檢查有效性: {$var}\n";
return $var;
}
}
$values = array(1,2,3);
$it = new MyIterator($values);
foreach ($it as $k => $v) {
print "此時(shí)鍵值對(duì) -- key $k: value $v\n\n";
}
運(yùn)行之后的結(jié)果如下:
我們可以想一下,如果把集合對(duì)象和對(duì)集合對(duì)象的操作放在一起,當(dāng)我們想換一種方式遍歷集合對(duì)象中元素時(shí),就需要修改集合對(duì)象了,違背“單一職責(zé)原則”,而迭代器模式將數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)結(jié)構(gòu)的算法分離開(kāi),兩者可獨(dú)立發(fā)展。
來(lái)看下迭代器的優(yōu)點(diǎn):
1.支持多種遍歷方式。比如有序列表,我們根據(jù)需要提供正序遍歷、倒序遍歷兩種迭代器。用戶只需要得到我們的迭代器,就可以對(duì)集合執(zhí)行遍歷操作
2.簡(jiǎn)化了聚合類。由于引入了迭代器,原有的集合對(duì)象不需要自行遍歷集合元素了
3.增加新的聚合類和迭代器類很方便,兩個(gè)維度上可各自獨(dú)立變化
4.為不同的集合結(jié)構(gòu)提供一個(gè)統(tǒng)一的接口,從而支持同樣的算法在不同的集合結(jié)構(gòu)上操作
缺點(diǎn)就是迭代器模式將存儲(chǔ)數(shù)據(jù)和遍歷數(shù)據(jù)的職責(zé)分離增加新的集合對(duì)象時(shí)需要增加對(duì)應(yīng)的迭代器類,類的個(gè)數(shù)成對(duì)增加,在一定程度上增加系統(tǒng)復(fù)雜度。
它的使用場(chǎng)景,我們可以參考如下幾點(diǎn):
1.訪問(wèn)一個(gè)聚合對(duì)象內(nèi)容而無(wú)須暴露它的內(nèi)部顯示
2.需要為聚合對(duì)象提供多種遍歷方式
3.為遍歷不同的聚合結(jié)構(gòu)提供一個(gè)統(tǒng)一的接口
我們要知道,最基本的迭代器接口是Iterator,來(lái)看下Iterator里面規(guī)范的方法:
Iterator extends Traversable {
/* 方法 */
abstract public mixed current ( void )//返回當(dāng)前元素
abstract public scalar key ( void )//返回當(dāng)前元素的鍵
abstract public void next ( void )//向前移動(dòng)到下一個(gè)元素
abstract public void rewind ( void )//返回到迭代器的第一個(gè)元素
abstract public boolean valid ( void )//檢查當(dāng)前位置是否有效
}
完事,我們?nèi)绻M(jìn)行遍歷的類必須實(shí)現(xiàn)Iterator里面的抽象方法,如下:
class Season implements Iterator{
private $position = 0;//指針指向0
private $arr = array('春','夏','秋','冬');
public function rewind(){
return $this -> position = 0;
}
public function current(){
return $this -> arr[$this -> position];
}
public function key(){
return $this -> position;
}
public function next() {
++$this -> position;
}
public function valid() {
return isset($this -> arr[$this -> position]);
}
}
$obj = new Season;
foreach ($obj as $key => $value) {
echo $key.':'.$value."\n";
}
最后,咱們來(lái)看一個(gè)網(wǎng)上找的用迭代器模式來(lái)實(shí)現(xiàn)的一個(gè)斐波那契數(shù)列。
我們都知道,斐波那契數(shù)列通常做法是用遞歸實(shí)現(xiàn),當(dāng)然還有其它的方法,咱們這里用PHP的迭代器來(lái)實(shí)現(xiàn)一個(gè)斐波納契數(shù)列,幾乎沒(méi)有什么難度,只是把類里的next()方法重寫(xiě)了一次。注釋已經(jīng)寫(xiě)到代碼中,也是相當(dāng)好理解的,如下:
class Fibonacci implements Iterator {
private $previous = 1;
private $current = 0;
private $key = 0;
public function current() {
return $this->current;
}
public function key() {
return $this->key;
}
public function next() {
// 關(guān)鍵在這里
// 將當(dāng)前值保存到 $newprevious
$newprevious = $this->current;
// 將上一個(gè)值與當(dāng)前值的和賦給當(dāng)前值
$this->current += $this->previous;
// 前一個(gè)當(dāng)前值賦給上一個(gè)值
$this->previous = $newprevious;
$this->key++;
}
public function rewind() {
$this->previous = 1;
$this->current = 0;
$this->key = 0;
}
public function valid() {
return true;
}
}
$seq = new Fibonacci;
$i = 0;
foreach ($seq as $f) {
echo "$f ";
if ($i++ === 15) break;
}
輸出的結(jié)果如下:
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610
好啦,本次記錄就到這里了。
更多關(guān)于PHP相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《php面向?qū)ο蟪绦蛟O(shè)計(jì)入門(mén)教程》、《PHP數(shù)組(Array)操作技巧大全》、《PHP基本語(yǔ)法入門(mén)教程》、《PHP運(yùn)算與運(yùn)算符用法總結(jié)》、《php字符串(string)用法總結(jié)》、《php+mysql數(shù)據(jù)庫(kù)操作入門(mén)教程》及《php常見(jiàn)數(shù)據(jù)庫(kù)操作技巧匯總》
希望本文所述對(duì)大家PHP程序設(shè)計(jì)有所幫助。
欄 目:PHP編程
下一篇:PHP 實(shí)現(xiàn)超簡(jiǎn)單的SESSION與COOKIE登錄驗(yàn)證功能示例
本文標(biāo)題:PHP設(shè)計(jì)模式之迭代器(Iterator)模式入門(mén)與應(yīng)用詳解
本文地址:http://www.jygsgssxh.com/a1/PHPbiancheng/11050.html
您可能感興趣的文章
- 04-02關(guān)于txt數(shù)據(jù)庫(kù)php的信息
- 04-02php本站才可以請(qǐng)求數(shù)據(jù) php本地?cái)?shù)據(jù)庫(kù)
- 04-02網(wǎng)頁(yè)里php操作數(shù)據(jù)庫(kù) php網(wǎng)頁(yè)例子
- 04-02php打印請(qǐng)求數(shù)據(jù) php打印輸出結(jié)果
- 04-02php數(shù)據(jù)庫(kù)地址 phpstudy 數(shù)據(jù)庫(kù)
- 04-02php插入數(shù)據(jù)庫(kù)為亂碼 php連接數(shù)據(jù)庫(kù)亂碼
- 04-02php數(shù)據(jù)庫(kù)數(shù)據(jù)相加 php數(shù)據(jù)庫(kù)添加數(shù)據(jù)語(yǔ)句
- 04-02php數(shù)據(jù)庫(kù)輸入變量 php里輸出數(shù)據(jù)庫(kù)數(shù)據(jù)函數(shù)
- 04-02數(shù)據(jù)權(quán)限架構(gòu)思路php 數(shù)據(jù)權(quán)限設(shè)計(jì)方案
- 04-02php如何用導(dǎo)入數(shù)據(jù) php用來(lái)導(dǎo)入其他文件的語(yǔ)句


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02php本站才可以請(qǐng)求數(shù)據(jù) php本地?cái)?shù)據(jù)庫(kù)
- 04-02關(guān)于txt數(shù)據(jù)庫(kù)php的信息
- 04-02php打印請(qǐng)求數(shù)據(jù) php打印輸出結(jié)果
- 04-02網(wǎng)頁(yè)里php操作數(shù)據(jù)庫(kù) php網(wǎng)頁(yè)例子
- 04-02php插入數(shù)據(jù)庫(kù)為亂碼 php連接數(shù)據(jù)庫(kù)亂
- 04-02php數(shù)據(jù)庫(kù)地址 phpstudy 數(shù)據(jù)庫(kù)
- 04-02php數(shù)據(jù)庫(kù)數(shù)據(jù)相加 php數(shù)據(jù)庫(kù)添加數(shù)據(jù)
- 04-02數(shù)據(jù)權(quán)限架構(gòu)思路php 數(shù)據(jù)權(quán)限設(shè)計(jì)方
- 04-02php數(shù)據(jù)庫(kù)輸入變量 php里輸出數(shù)據(jù)庫(kù)數(shù)
- 04-02php如何用導(dǎo)入數(shù)據(jù) php用來(lái)導(dǎo)入其他文
隨機(jī)閱讀
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10delphi制作wav文件的方法
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 04-02jquery與jsp,用jquery
- 01-10C#中split用法實(shí)例總結(jié)
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什


