[Python設計模式] 第20章 挨個買票——迭代器模式

github地址:https://github.com/cheesezh/python_design_patternspython

迭代器模式

迭代器模式,提供一種方法順序訪問一個聚合對象中各個元素,而又不暴露該對象的內部表示[DP]。git

當須要訪問一個彙集對象,並且無論這些對象是什麼都須要遍歷的時候,就應該考慮使用迭代器模式。github

當須要對彙集有多種方式遍歷時,也能夠考慮使用迭代器模式。app

迭代器爲遍歷不一樣的彙集結構提供如開始,下一個,是否結束,當前哪一項等統一接口。code

from abc import ABCMeta, abstractmethod


class Iterator():
    """
    迭代器抽象類,定義獲得開始對象,獲得下一對象,判斷是否結尾,獲得當前對象等方法
    """
    __metaclass__ = ABCMeta
    
    @abstractmethod
    def first(self):
        pass
    
    @abstractmethod
    def next(self):
        pass
    
    @abstractmethod
    def is_done(self):
        pass
    
    @abstractmethod
    def current_item(self):
        pass
    
    
class Aggregate():
    """
    彙集抽象類
    """
    __metaclass__ = ABCMeta
    
    @abstractmethod
    def create_iterator(self):
        pass
    
    
class ConcreteIterator(Iterator):
    """
    具體迭代器類
    """
    def __init__(self, aggregate):
        # 定義一個具體的彙集對象,初始化時將具體的彙集對象傳入
        self.aggregate = aggregate
        self.current = 0
        
    def first(self):
        # 獲得彙集的第一個對象
        return self.aggregate.get_value(0)
    
    def next(self):
        # 獲得彙集的下一個對象
        ret = None
        self.current += 1
        if self.current < self.aggregate.length:
            ret = self.aggregate.get_value(self.current)
        return ret
    
    def is_done(self):
        return True if self.current >= self.aggregate.length else False
    
    def current_item(self):
        return self.aggregate.get_value(self.current)
    
    
class ConcreteAggregate(Aggregate):
    """
    具體彙集類
    """
    def __init__(self):
        self.list = []
        self.length = 0
    
    def create_iterator(self):
        return ConcreteIterator(self)
    
    def create_iterator_desc(self):
        return ConcreteIteratorDesc(self)
    
    def insert_value(self, value):
        self.list.append(value)
        self.length += 1
        
    def get_value(self, index):
        return self.list[index]

    
def main():
    agg = ConcreteAggregate()
    agg.insert_value("aa")
    agg.insert_value("bb")
    agg.insert_value("cc")
    agg.insert_value("dd")
    agg.insert_value("ee")
    
    i = agg.create_iterator()
    
    item = i.first()
    while i.is_done() == False:
        print("{} 買車票".format(i.current_item()))
        i.next()
        
main()
aa 買車票
bb 買車票
cc 買車票
dd 買車票
ee 買車票

逆序遍歷

class ConcreteIteratorDesc(Iterator):
    """
    具體迭代器類,逆序遍歷
    """
    def __init__(self, aggregate):
        # 定義一個具體的彙集對象,初始化時將具體的彙集對象傳入
        self.aggregate = aggregate
        self.current = self.aggregate.length-1
        
    def first(self):
        # 獲得彙集的第一個對象
        return self.aggregate.get_value(self.aggregate.length-1)
    
    def next(self):
        # 獲得彙集的下一個對象
        ret = None
        self.current -= 1
        if self.current >= 0:
            ret = self.aggregate.get_value(self.current)
        return ret
    
    def is_done(self):
        return True if self.current < 0 else False
    
    def current_item(self):
        return self.aggregate.get_value(self.current)
    
    
def main():
    agg = ConcreteAggregate()
    agg.insert_value("aa")
    agg.insert_value("bb")
    agg.insert_value("cc")
    agg.insert_value("dd")
    agg.insert_value("ee")
    
    i = agg.create_iterator_desc()
    
    item = i.first()
    while i.is_done() == False:
        print("{} 買車票".format(i.current_item()))
        i.next()
        
main()
ee 買車票
dd 買車票
cc 買車票
bb 買車票
aa 買車票

點評

總的來講,迭代器模式就是分離了集合對象的遍歷行爲,抽象出一個迭代器類來負責,這樣既能夠作到不暴露集合的內部結構,又能夠讓外部代碼透明的訪問集合內部的數據。orm

相關文章
相關標籤/搜索