大話設計模式:第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, "請買車票!")
大鳥 請買車票!
小菜 請買車票!
老外 請買車票!
公交內部員工 請買車票!
小偷 請買車票!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章