大话设计模式:第20章 迭代器模式

第20章:迭代器模式

迭代器模式

迭代器模式(iterator),提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。

迭代器模式适用情况:

  1. 需要访问一个聚集对象,而且不管这些对象是什么都需要遍历

  2. 需要对聚集有多种遍历方式

迭代器模式为遍历不同的聚集结构提供如开始、下一个、是否结束、当前哪一项等统一的接口。

在这里插入图片描述

迭代器模式分离了集合对象的遍历行为,抽象出-个迭代器类来负责,这样既可以不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。迭代器模式在访问数组、集合、列表等数据时,尤其是数据库数据操作时,应用非常普遍,各种高级语言都对它进行了封装。

Iterator迭代器抽象类

在这里插入图片描述

Aggregate聚集抽象类

在这里插入图片描述

ConcreteIteratorConcreteIteratorDesc具体迭代器类,继承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, "请买车票!")
大鸟 请买车票!
小菜 请买车票!
老外 请买车票!
公交内部员工 请买车票!
小偷 请买车票!

猜你喜欢

转载自blog.csdn.net/zhaoyin214/article/details/105989336