首页 > 其他分享 >设计模式(十六)迭代器

设计模式(十六)迭代器

时间:2023-12-06 11:13:27浏览次数:28  
标签:遍历 聚合 迭代 十六 products 设计模式 public objectList

一、定义

提供一种方法顺序访问一个聚合对象中的各个元素,且不用暴露该对象的内部表示。迭代器模式是一种对象行为型模式,又称为游标(Cursor)模式。

二、描述

在软件系统中,聚合对象拥有两个职责:一是存储数据,二是遍历数据。从依赖性来看,前者是聚合对象的基本职责,而后者既是可变化的,又是可分离的。因此,可以将遍历数据的行为从聚合对象中分离出来,封装在迭代器对象中,由迭代器来提供遍历聚合对象内部数据的行为,这将简化聚合对象的设计,更加符合单一职责原则的要求。包含以下四个角色:1、Iterator(抽象迭代器):它定义了访问和遍历元素的接口,声明了用于遍历数据元素的方法。
2、ConcreteIterator(具体迭代器):它实现了抽象迭代器接口,完成对聚合对象的遍历,同时在具体迭代器中通过游标来记录在聚合对象中所处的当前位置,在具体实现时,游标通常是一个表示位置的非负整数。
3、Aggregate(抽象聚合类):它用于存储和管理元素对象,声明一个CreateIterator()方法用于创建一个迭代器对象,充当抽象迭代器工厂角色。
4、ConcreteAggregate(具体聚合类):它是抽象聚合类的子类,实现了在抽象聚合类中声明的CreateIterator()方法,该方法返回一个与该具体聚合类对应的具体迭代器ConcreteIterator实例。

三、例子

X公司为某商场开发了一套销售管理系统,在对该系统进行分析和设计时,M公司开发人员发现经常需要对系统中的商品数据、客户数据等进行遍历,为了复用这些遍历代码,开发人员设计了一个抽象的数据聚合类AbstractObjectList,而将存储商品和客户登记的类作为其子类。

AbstractObjectList:抽象聚合类

public abstract class AbstractObjectList
{
    protected IList<object> objectList = new List<object>();

    public AbstractObjectList (IList<object> objectList)
    {
        this.objectList = objectList;
    }

    public void AddObject(object obj)
    {
        this.objectList.Add(obj);
    }

    public void RemoveObject(object obj)
    {
        this.objectList.Remove(obj);
    }

    public IList<Object> GetObjectList()
    {
        return this.objectList;
    }

    // 声明创建迭代器对象的抽象工厂方法
    public abstract AbstractIterator CreateIterator();
}

ProductList、ProductIterator:具体聚合类、具体迭代器,具体迭代器是具体聚合类的内部类

public class ProductList : AbstractObjectList
{
    public ProductList(IList<object> objectList) : base(objectList)
    {
    }

    public override AbstractIterator CreateIterator()
    {
        return new ProductIterator(this);
    }

    private class ProductIterator : AbstractIterator
    {
        private ProductList productList;
        private IList<object> products;
        private int cursor1;    // 定义一个游标,用于记录正向遍历的位置
        private int cursor2;    // 定义一个游标,用于记录逆向遍历的位置

        public ProductIterator(ProductList productList)
        {
            this.productList = productList;
            this.products = productList.GetObjectList();       // 获取集合对象
            this.cursor1 = 0;                                  // 设置正向遍历游标的初始值
            this.cursor2 = this.products.Count - 1;            // 设置逆向遍历游标的初始值
        }

        public object GetNextItem()
        {
            return products[cursor1];
        }

        public object GetPreviousItem()
        {
            return products[cursor2];
        }

        public bool IsFirst()
        {
            return cursor2 == -1;
        }

        public bool IsLast()
        {
            return cursor1 == products.Count;
        }

        public void Next()
        {
            if (cursor1 < products.Count)
            {
                cursor1++;
            }
        }

        public void Previous()
        {
            if (cursor2 > -1)
            {
                cursor2--;
            }
        }
    }
}

AbstractIterator:抽象迭代器

public interface AbstractIterator
{
    void Next();               // 移动至下一个元素
    bool IsLast();             // 判断是否为最后一个元素
    void Previous();           // 移动至上一个元素
    bool IsFirst();            // 判断是否为第一个元素
    object GetNextItem();      // 获取下一个元素
    object GetPreviousItem();  // 获取上一个元素
}

Program:客户端测试类

IList<object> products = new List<object>();
products.Add("倚天剑");
products.Add("屠龙刀");
products.Add("断肠草");
products.Add("葵花宝典");
products.Add("四十二章经");

AbstractObjectList objectList = new ProductList(products);      // 创建聚合对象
AbstractIterator iterator = objectList.CreateIterator();        // 创建迭代器对象

Console.WriteLine("正向遍历");
while (!iterator.IsLast())
{
    Console.Write(iterator.GetNextItem() + ",");
    iterator.Next();
}

Console.WriteLine();
Console.WriteLine("-------------------------------------------------------");
Console.WriteLine("逆向遍历");
while (!iterator.IsFirst())
{
    Console.Write(iterator.GetPreviousItem() + ",");
    iterator.Previous();
}
Console.ReadLine();

四、总结

1、优点

(1)迭代器模式支持以不同方式遍历一个聚合对象,在同一个聚合对象上可以定义多种便利方式。在迭代器模式中,只需用一个不同的迭代器来替换原有迭代器即可改变遍历算法,也可以自己定义迭代器的子类以支持新的遍历方法。
(2)迭代器模式简化了聚合类。由于引入了迭代器,在原有的聚合对象中不需要再自行提供数据遍历等方法,这样可以简化聚合类的设计。
(3)在迭代器模式中,由于引入了抽象层,增加新的聚合类和迭代器类都很方便,无须修改原有代码,符合开闭原则。

2、缺点

(1)由于迭代器模式将存储数据和遍历数据的职责分离,在增加新的聚合类需要对应增加新的迭代器类,类的个数会成对增加,这在一定程度上增加了系统的复杂性。
(2)抽象迭代器的设计难度较大,需要充分考虑系统将来的扩展。在自定义迭代器时,创建一个考虑全面的抽象迭代器并不是一件很容易的事情。

迭代器模式在.Net中,可以通过实现IEnumberable接口即可,不再需要单独实现,迭代器模式中的聚集接口和迭代器接口都已经存在了,其中IEnumerator接口扮演的就是迭代器角色,IEnumberable接口则扮演的就是抽象聚集的角色,其中定义了GetEnumerator()方法。

标签:遍历,聚合,迭代,十六,products,设计模式,public,objectList
From: https://www.cnblogs.com/WinterSir/p/17511722.html

相关文章

  • go设计模式之工厂模式
    Go语言实现设计模式之工厂方法模式原创 汀风 汀风说后端 2023-12-0608:10 发表于北京汀风说后端编程知识普及,让学习与工作变得更简单。18篇原创内容公众号摘要:工厂方法模式是一种创建型设计模式,它将对象的创建延迟到子类中进行,通过定义一个创建对......
  • 迭代器和生成器、异常捕获
    一、迭代器(Iterator)1、可迭代对象(Iterable)和可索引对象存储了元素的一个容器对象,且容器中的元素可以通过“__iter__()”方法或“__getitem__()”方法访问。可迭代对象不能独立进行迭代,可通过“for…in”遍历来完成2、常见的可迭代对象字符串、列表、元组、字典、集合、文件......
  • 23种设计模式——抽象工厂模式
    今天我们来学习一下第三种设计模式——抽象工厂模式,概念:所谓抽象工厂模式就是提供一个接口,用于创建相关或者依赖对象的家族,而不需要明确指定具体类。它允许客户端使用抽象的接口来创建一组相关的产品,而不需要关心实际产出的具体产品是什么。这样一来,客户就可以从具体的产品中被......
  • 代码随想训练营第五十六天(Python)| 583. 两个字符串的删除操作、72. 编辑距离
    583.两个字符串的删除操作classSolution:defminDistance(self,word1:str,word2:str)->int:n,m=len(word1),len(word2)#dp数组代表使得word1以i-1结尾和word2以j-1结尾相同的最小步数dp=[[0]*(m+1)for_inrange(n+......
  • Salesforce LWC学习(四十六) 自定义Datatable实现cell onclick功能
    本篇参考:https://developer.salesforce.com/docs/component-library/bundle/lightning-datatable背景:我们有时会有这种类似的需求,显示Account列表,Account列除了需要显示Account信息,还需要显示其他的内容,比如当前Account有多少Opportunity,有多少Contact数量。点击数量信息,可以显示......
  • python 可迭代对象 迭代器 生成器
    一个对象若要用for循环则需实现def__iter__(self,item)或def__iter__(self,item)方法可迭代对象实现了def__iter__(self,item)方法  迭代器  实现了def__iter__(self,item)和def__next__(self)方法  迭代器一定是可迭代对象可迭代对象不一定是迭代器from......
  • 小谈设计模式(11)—模板方法模式
    (小谈设计模式(11)—模板方法模式)主要对目前市面上常见的23种设计模式进行逐一分析和总结,希望有兴趣的小伙伴们可以看一下,会持续更新的。希望各位可以监督我,我们一起学习进步,加油,各位。模板方法模式这是一种行为型设计模式,用于定义算法的框架,将算法的具体实现延迟到子类中。角......
  • Unity DOTS系列之System中如何使用SystemAPI.Query迭代数据
    最近DOTS发布了正式的版本,我们来分享一下System中如何基于SystemAPI.Query来迭代World中的数据,方便大家上手学习掌握UnityDOTS开发。SystemAPI.Query的使用System有两种,一种是Unmanaged的ISystem,一种是managed的SystemBase,这两种System都可以通过SystemAPI.Query来迭代与......
  • 设计模式之外观模式
    1.定义提供了一个统一的接口,用来访问子系统中的一组接口2.口语化表述工厂里组装台灯,流程、配件等有多种方式,每种台灯有自己的生产线现在,需要某一种台灯,一种方式是直接去找这个台灯的生产线生成,这会令人烦恼,因为寻找是一件无聊而繁琐的事情另一种方式是成立一个工厂前台,需要......
  • “数据结构”模式之迭代器(Iterator)模式
    常常有一些组件在内部具有特定的数据结构,如果让客户程序依赖这些特定的数据结构,将极大地破坏组件的复用。这时候,将这些特定数据结构封装在内部,在外部提供统一的接口,来实现与特定数据结构无关的访问,是一种行之有效的解决方案。典型模式:CompositeIteratorChainofResposibilit......