一說到這個模式,就不得不提循環語句。在《大話設計模式》中,做者說道這個模式如今的學習意義更大於實際意義,這是爲何呢?固然就是被foreach這貨給整得。任何語言都有這種相似的語法能夠方便快捷的對數組、對象進行遍歷,從而讓迭代器模式從高高在上的23大設計模式中的明星慢慢成爲了路人。特別是咱們這門PHP語言,PHP的強大之處就在於對於數組的靈活操做,自己就是hashmap的結構,天然會有各類方便的數組操做語法,而foreach也是咱們最經常使用的語句,甚至比for還經常使用。php
GoF定義:提供一種方法順序訪問一個聚合對象中各個元素,而又不需暴露該對象的內部表示git
GoF類圖github
代碼實現面試
interface Aggregate {
public function CreateIterator();
}
class ConcreteAggregate implements Aggregate {
public function CreateIterator() {
$list = [
"a",
"b",
"c",
"d",
];
return new ConcreteIterator($list);
}
}
複製代碼
首先是聚合類,也就是能夠進行迭代的類,這裏由於我是面向對象的設計模式,因此迭代器模式針對的是對一個類的內容進行迭代。在這裏,其實咱們也只是模擬了一個數組交給了迭代器。數據庫
interface MyIterator {
public function First();
public function Next();
public function IsDone();
public function CurrentItem();
}
class ConcreteIterator implements MyIterator {
private $list;
private $index;
public function __construct($list) {
$this->list = $list;
$this->index = 0;
}
public function First() {
$this->index = 0;
}
public function Next() {
$this->index++;
}
public function IsDone() {
return $this->index >= count($this->list);
}
public function CurrentItem() {
return $this->list[$this->index];
}
}
複製代碼
迭代器閃亮登場,主要實現了四個方法來對集合數據進行操做。有點像學習數據結構或數據庫時對遊標進行的操做。用First()和Next()來移動遊標,用CurrentItem()來得到當前遊標的數據內容,用IsDone()來確認是否還有下一條數據。因此,這個模式也另稱爲遊標模式。json
$agreegate = new ConcreteAggregate();
$iterator = $agreegate->CreateIterator();
while (!$iterator->IsDone()) {
echo $iterator->CurrentItem(), PHP_EOL;
$iterator->Next();
}
複製代碼
客戶端直接使用while來進行操做便可。設計模式
咱們的手機工廠不得了,本身組裝了一條生產線,這條生產線主要是作什麼的呢?成型機咱們已經交給富X康來搞定了,咱們這條線就是給手機刷顏色的。當咱們把全部已經交貨的手機(Aggregate)放到不一樣的生產線後(Iterator),就會一臺一臺的幫咱們刷上當前生產線的顏色,是否是很強大!!科技不止於換殼,這條線還在,咱們就能夠再作別的事兒,好比加點掛繩什麼的,反正只要能一臺一臺的經過我就能裝上東西,你說好用很差用!!數組
完整代碼:github.com/zhangyue050…服務器
實例仍是圍繞着咱們的短信發送來看。這一次,咱們的業務需求是儘快的發一批通知短信給用戶,由於活動的時候可不等人啊。在以前咱們會使用多個腳原本把用戶手機號分紅多組來進行發送。如今咱們能夠用swoole來直接多線程的發送。所要達到的效果其實就是爲了快速的把成百上千的短信發完。這個時候咱們也會作一些策略,好比數據庫裏是100條要送的短信,有個字段是發送狀態,一個線程正序的發,一個線程倒序的發,當正序和倒序都發送到50條的時候其實已經同步的發完這100條了,不過也有可能會有失敗的狀況出現,這時,兩個線程還會繼續去發送那些上次發送不成功的信息,這樣可以最大程度的確保發送的效率和到達率。swoole
消息發送迭代器類圖
<?php
interface MsgIterator {
public function First();
public function Next();
public function IsDone();
public function CurrentItem();
}
// 正向迭代器
class MsgIteratorAsc implements MsgIterator {
private $list;
private $index;
public function __construct($list) {
$this->list = $list;
$this->index = 0;
}
public function First() {
$this->index = 0;
}
public function Next() {
$this->index++;
}
public function IsDone() {
return $this->index >= count($this->list);
}
public function CurrentItem() {
return $this->list[$this->index];
}
}
// 反向迭代器
class MsgIteratorDesc implements MsgIterator {
private $list;
private $index;
public function __construct($list) {
// 反轉數組
$this->list = array_reverse($list);
$this->index = 0;
}
public function First() {
$this->index = 0;
}
public function Next() {
$this->index++;
}
public function IsDone() {
return $this->index >= count($this->list);
}
public function CurrentItem() {
return $this->list[$this->index];
}
}
interface Message {
public function CreateIterator($list);
}
class MessageAsc implements Message {
public function CreateIterator($list) {
return new MsgIteratorAsc($list);
}
}
class MessageDesc implements Message {
public function CreateIterator($list) {
return new MsgIteratorDesc($list);
}
}
// 要發的短信號碼列表
$mobileList = [
'13111111111',
'13111111112',
'13111111113',
'13111111114',
'13111111115',
'13111111116',
'13111111117',
'13111111118',
];
// A服務器腳本或使用swoole發送正向的一半
$serverA = new MessageAsc();
$iteratorA = $serverA->CreateIterator($mobileList);
while (!$iteratorA->IsDone()) {
echo $iteratorA->CurrentItem(), PHP_EOL;
$iteratorA->Next();
}
// B服務器腳本或使用swoole同步發送反向的一半
$serverB = new MessageDesc();
$iteratorB = $serverB->CreateIterator($mobileList);
while (!$iteratorB->IsDone()) {
echo $iteratorB->CurrentItem(), PHP_EOL;
$iteratorB->Next();
}
複製代碼
說明
彩蛋
PHP中的Iterator接口已經爲咱們準備好了一套標準的Iterator模式的實現,並且(這裏須要畫重點),實現這個接口的類能夠用foreach來遍歷哦!
文檔中相關的接口均可以看看,更重要的是,PHP的SPL擴展中,也爲咱們準備了不少經常使用的迭代器封裝。要知道,面試的時候要是能說出這裏面的幾個來,那面試官但是也會另眼相看的哦!
SPL迭代器:www.php.net/manual/zh/s…
迭代器很好玩吧,並且和觀察者同樣,PHP自己的擴展庫居然爲咱們準備了不少接口。日常寫代碼的時候是否是能夠炫炫技了呢!!別急,咱們進入設計模式的世界並不久,還有不少有意思的設計模式等着咱們去學習,就像原型模式,這貨幹嗎的?複製本身哦,克隆人的戰爭!