第20章:迭代器模式
迭代器模式
迭代器模式(iterator),提供一種方法順序訪問一個聚合對象中各個元素,而又不暴露該對象的內部表示。
迭代器模式適用情況:
-
需要訪問一個聚集對象,而且不管這些對象是什麼都需要遍歷
-
需要對聚集有多種遍歷方式
迭代器模式爲遍歷不同的聚集結構提供如開始、下一個、是否結束、當前哪一項等統一的接口。
迭代器模式分離了集合對象的遍歷行爲,抽象出-個迭代器類來負責,這樣既可以不暴露集合的內部結構,又可讓外部代碼透明地訪問集合內部的數據。迭代器模式在訪問數組、集合、列表等數據時,尤其是數據庫數據操作時,應用非常普遍,各種高級語言都對它進行了封裝。
Iterator
迭代器抽象類
Aggregate
聚集抽象類
ConcreteIterator
、ConcreteIteratorDesc
具體迭代器類,繼承Iterator
ConcreteAggregate
具體聚集類,繼承Aggregate
客戶端代碼
運行結果
.NET的迭代器實現
IEumerator
支持對非泛型集合的簡單迭代接口。
IEumerable
公開枚舉數,該枚舉數支持在非泛型集合上進行簡單迭代。
客戶端代碼
foreach in
在編譯器中的工作
迭代器模式示例
任務:公交人工售票
GoF
實現
from abc import ABC, abstractmethod
from typing import Any, Text
class Iterator(ABC):
"""
迭代器抽象類
"""
@abstractmethod
def first(self) -> Any:
pass
@abstractmethod
def next_(self) -> Any:
pass
@abstractmethod
def is_done(self) -> bool:
pass
@abstractmethod
def current_item(self) -> Any:
pass
class Aggregate(ABC):
"""
聚集抽象類
"""
@abstractmethod
def create_iterator(self) -> Iterator:
pass
class ConcreteIterator(Iterator):
"""
具體迭代器類
"""
def __init__(self, aggregate: Aggregate) -> None:
self.__aggregate = aggregate
self.__current = 0
def first(self) -> Any:
return self.__aggregate[0]
def next_(self) -> Any:
ret = None
self.__current += 1
if self.__current < self.__aggregate.count:
ret = self.__aggregate[self.__current]
return ret
def is_done(self) -> bool:
return True if self.__current >= self.__aggregate.count else False
def current_item(self) -> Any:
return self.__aggregate[self.__current]
class ConcreteIteratorDesc(Iterator):
"""
具體迭代器類(逆序)
"""
def __init__(self, aggregate: Aggregate) -> None:
self.__aggregate = aggregate
self.__current = self.__aggregate.count - 1
def first(self) -> Any:
return self.__aggregate[-1]
def next_(self) -> Any:
ret = None
self.__current -= 1
if self.__current > self.__aggregate.count:
ret = self.__aggregate[self.__current]
return ret
def is_done(self) -> bool:
return True if self.__current <= 0 else False
def current_item(self) -> Any:
return self.__aggregate[self.__current]
class ConcreteAggregate(Aggregate):
"""
具體聚集類
"""
def __init__(self):
self.__items = []
def create_iterator(self) -> Iterator:
return ConcreteIterator(self)
@property
def count(self) -> int:
return len(self.__items)
def __getitem__(self, index: int) -> Any:
"""
item[idx]
"""
return self.__items[index]
def __setitem__(self, index: int, value: Any) -> None:
"""
mapping op (items[idx] = value) to insert
"""
# self.__items[index] = value
self.__items.insert(index, value)
def __delitem__(self, index: int) -> None:
"""
del item[idx]
"""
self.__items.pop(index)
# def insert(self, index: int, value: Any) -> None:
# self.__items.insert(index, value)
# 客戶端代碼
if __name__ == "__main__":
a = ConcreteAggregate()
a[0] = "大鳥"
a[1] = "小菜"
a[2] = "行李"
a[3] = "老外"
a[4] = "公交內部員工"
a[5] = "小偷"
print("** 順序 **")
i = ConcreteIterator(a)
item = i.first()
while not i.is_done():
print(i.current_item(), "請買車票!")
i.next_()
print("** 逆序 **")
i_ = ConcreteIteratorDesc(a)
item = i_.first()
while not i_.is_done():
print(i_.current_item(), "請買車票!")
i_.next_()
** 順序 **
大鳥 請買車票!
小菜 請買車票!
行李 請買車票!
老外 請買車票!
公交內部員工 請買車票!
小偷 請買車票!
** 逆序 **
小偷 請買車票!
公交內部員工 請買車票!
老外 請買車票!
行李 請買車票!
小菜 請買車票!
Python迭代器模式
# 客戶端代碼
if __name__ == "__main__":
a = []
a.append("大鳥")
a.append("小菜")
a.append("老外")
a.append("公交內部員工")
a.append("小偷")
for item in a:
print(item, "請買車票!")
大鳥 請買車票!
小菜 請買車票!
老外 請買車票!
公交內部員工 請買車票!
小偷 請買車票!