第10章 迭代模式
从生活中领悟迭代模式
医院的排号系统就像病人队伍的大管家,通过数字化的方式精确地维护着先来先就诊的秩序。医生不用在乎外面有多少人在等待,更不需要了解每一个人的名字和具体信息。他只要在诊断完一个病人后按一下按钮,排号系统就会自动为他呼叫下一位病人,这样医生就可专注于病情的诊断!这个排号系统就如同程序设计中的迭代模式。
为什么不用python的集合(可迭代的),来简化这个问题呢?
主要有以下两个原因:
- (1)for…in…的方式不能实现医生诊断完一个病人后呼叫下一个(next)病人的功能。只能一次性全部遍历完。
- (2)这里讲的迭代模式是一个一般化的方法,其他的编程语言对迭代器的支持并没有这么好,需要自己实现。
10.2.2 迭代模式设计思想
迭代模式也称为迭代器模式。迭代器其实就是一个指向容器中当前元素的指针,这个指针可以返回当前所指向的元素,可以移到下一个元素的位置,通过这个指针可以遍历容器中的所有元素。
10.3 迭代模式的模型抽象
迭代模式的框架
class BaseIterator:
"""迭代器"""
def __init__(self,data):
self.__data=data
self.toBegin()
def toBegin(self):
"""指针移动到初始位置"""
self.__curIdx=-1
def toEnd(self):
"""指针移动到末尾位置"""
self.__curIdx=len(self.__data)
def next(self):
"""移动至下一个元素"""
if (self.__curIdx<len(self.__data)-1):
self.__curIdx+=1
return True
else:
return False
def previous(self):
"""获取前一个元素"""
if (self.__curIdx>0):
self.__curIdx-=1
return True
else:
return False
def current(self):
"""获取当前元素"""
return self.__data[self.__curIdx] if (self.__curIdx<len(self.__data) and self.__curIdx>=0) else None
def testBaseIterator():
print("从前向后遍历")
iterator=BaseIterator(range(0,10))
while (iterator.next()):
customer=iterator.current()
print(customer,end="\t")
print("从后向前遍历")
iterator.toEnd()
while (iterator.previous()):
customer=iterator.current()
print(customer,end="\t")
testBaseIterator()
#增加这些功能之后,我们就可以实现以下操作:
#(1)可以从前往后遍历,也可以从后往前遍历。
#(2)可以实现多次重复遍历。
10.3.3 类图
一个迭代器一般对应着一个容器类,而一个容器会包含多个元素,这些元素可能会有不同的子类。迭代模式的类图如图10-3所示。
图10-4 具有层级结构的容器的迭代器实现
1.设计要点
(1)了解容器的数据结构及可能的层次结构。
(2)根据需要确定迭代器要实现的功能,如next()、previous()、current()、toBegin()、toEnd()中的一个或几个。
2.迭代模式的优缺点
优点:
(1)迭代器模式将存储数据和遍历数据的职责分离。
(2)简化了聚合数据的访问方式。
(3)可支持多种不同的方式(如顺序和逆序)遍历一个聚合对象。
10.4 应用场景
- (1)集合的内部结构复杂,不想暴露对象的内部细节,只提供精简的访问方式。
- (2)需要提供统一的访问接口,从而对不同的集合使用统一的算法。
- (3)需要为一系列聚合对象提供多种不同的访问方式。