第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, "请买车票!")
大鸟 请买车票!
小菜 请买车票!
老外 请买车票!
公交内部员工 请买车票!
小偷 请买车票!