前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python设计模式(10):迭代器模式

Python设计模式(10):迭代器模式

作者头像
不可言诉的深渊
发布2019-07-26 17:28:09
7350
发布2019-07-26 17:28:09
举报

导言

在面向对象的软件设计中,如果一个系统有比较复杂的数据结构,客户程序往往没有必要详细地知道其内部的实现。为了使用方便,该系统应该提供给客户程序一种遍历方法。该遍历方法类似于使用电视机遥控器来浏览电视频道,客户程序只要按照顺序调用 next()方法即可得到相应的数据。本节介绍如何给复杂的聚合型数据结构提供一个遍历方法的设计模式——迭代器模式(Iterator Pattern)。

迭代器模式的关键思想是将对列表的访问和便利从列表对象中分离出来,放入一个独立的迭代器对象中。迭代器类定义了访问该列表元素的接口。迭代器类提供的方法负责跟踪当前的元素,即它知道哪些元素已经遍历过了,哪些元素还没有被遍历。

迭代器模式能够提供一种方法按照顺序访问一个聚合对象中的所有元素,而又不需要暴露该对象的内部表示。

迭代器模式的结构图如图所示。

迭代器模式的各组成部分及含义说明如下。

  1. Aggregate:聚合接口,其实现子类将创建并且维持一个一种数据类型的聚合体。另外,它还定义了创建相应迭代器对象的接口 createIterator。
  2. ConcreteAggregate:封装了一个数据存储结构,实现一个具体的集合,如列表、Java 类型 ArrayList 等。一个聚合对象包含一些其他的对象,目的是将这些对象组合成一个新的整体对象,该对象也叫做容器对象或者聚合对象。另外,该类提供了创建相应迭代器对象的方法 createIterator,该方法返回类型为 ConcreteIterator 的一个对象。
  3. Iterator:迭代器定义访问和遍历元素的接口。
  4. ConcreateIterator(Controller):具体迭代器实现迭代器接口,对该聚合遍历时跟踪当前位置。

值得注意的是,再迭代器模式类图的聚合部分,可以包含有几种不同的具体的聚合类(ConcreteAggregate)。这样,在迭代器部分,针对每个具体的聚合类,可以允许有一个或者多个具体的迭代器类。这些具体的迭代器类都实现同一个接口 Iterator。其好处可以为类似(但是不同)的聚合类设计/实现出类似(但是不同)的迭代器,便于复用。

协作关系指 ConcreteIterator 跟踪聚合类中的当前对象,并能够计算出待遍历的后继对象。

在创建列表迭代器的遍历对象之前,必须提供待遍历的列表,一旦有了该列表迭代器对象,就可以按照顺序访问该列表的各个元素。currentItem()操作返回列表中的当前元素,first()操作初始化迭代器,使当前元素指向列表的第一个元素。next()操作将当前元素指针向前推进一步,指向下一个元素。isDone()操作检查是否已经越过最后一个元素,也就是完成了这次遍历。

迭代器模式的优点如下。

  1. 迭代器模式支持以不同的方式遍历同一聚合,复杂的聚合可以用多种方式进行遍历。例如二叉树遍历方法有 4 种:先序遍历、中序遍历、后序遍历和层次遍历。可以将不同的遍历算法封装在不同的迭代器子类中,每个迭代器保持自己的遍历状态,因此可以进行多种不同方式的遍历。
  2. 当修改某一个遍历算法时不会影响其他的遍历算法。
  3. 当修改被遍历的聚合结构代码时,如果该聚合结构没有改变,则相应的遍历算法代码也不需要改变。
  4. 迭代器简化了聚合的接口。有了迭代器的遍历接口,聚合本身就不需要类似的遍历接口了。这样就简化了聚合的接口。
代码语言:javascript
复制
from abc import ABC, abstractmethod


class Aggregate(ABC):
    @abstractmethod
    def create_iterator(self):
        pass


class ConcreteAggregate(Aggregate):
    def __init__(self):
        self.data_structure = list(range(10))

    def create_iterator(self):
        return ConcreteIterator(self)


class Iterator(ABC):
    @abstractmethod
    def first(self):
        pass

    @abstractmethod
    def next(self):
        pass

    @abstractmethod
    def is_done(self):
        pass

    @abstractmethod
    def current_item(self):
        pass


class ConcreteIterator(Iterator):
    def __init__(self, aggregate):
        self.aggregate = aggregate
        self.first()

    def first(self):
        # noinspection PyAttributeOutsideInit
        self.index = 0

    def next(self):
        self.index += 1

    def is_done(self):
        if self.index == len(self.aggregate.data_structure):
            return True
        return False

    def current_item(self):
        return self.aggregate.data_structure[self.index]


class Client:
    @staticmethod
    def main():
        aggregate = ConcreteAggregate()
        iterator = aggregate.create_iterator()
        while not iterator.is_done():
            print(iterator.current_item())
            iterator.next()


if __name__ == '__main__':
    Client.main()
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-03-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python机器学习算法说书人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档