【愚公系列】2021年12月 二十三种设计模式(十六)-迭代器模式(Iterator Pattern)

简介: 【愚公系列】2021年12月 二十三种设计模式(十六)-迭代器模式(Iterator Pattern)

文章目录

前言

一、迭代器模式(Iterator Pattern)

二、使用步骤

角色

示例

传统迭代器实现

yield return迭代器实现

总结

优点

缺点

使用场景

前言

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。


提示:以下是本篇文章正文内容,下面案例可供参考


一、迭代器模式(Iterator Pattern)

迭代器模式属于行为型模式,它提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。


二、使用步骤

角色

1、迭代器(Iterator)


迭代器角色负责定义访问和遍历元素的接口;


2、具体迭代器(Concrete Iteraror)


具体迭代器角色实现了迭代器接口,并需要记录遍历中的当前位置;


3、聚合(Aggregate)


聚合角色负责定义获得迭代器角色的接口;


4、具体聚合(Concrete Aggregate)


具体聚合角色实现聚合角色接口。


示例

image.png

命名空间IteratorPattern中包含Person基类、People类、PelpleEnum类,另外包含一个苹果手机ApplePhone类,和BestEnum类。Person示例来自微软官方的 IEnumerable接口 介绍页面,BestEnum则使用.Net 2.0中的yield return关键字创建苹果手机信息序列。

namespace IteratorPattern

传统迭代器实现

public class Person {
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Person(string firstName, string lastName) {
        this.FirstName = firstName;
        this.LastName = lastName;
    }
}

Person类,包含First Name和Last Name。

public class People : IEnumerable {
    private Person[] _people = null;
    public People(Person[] pArray) {
        _people = new Person[pArray.Length];
        for (int i = 0; i < pArray.Length; i++) {
            _people[i] = pArray[i];
        }
    }
    public IEnumerator GetEnumerator() {
        return new PeopleEnum(_people);
    }
}

People类,实现IEnumerable接口。

public class PeopleEnum : IEnumerator {
    private Person[] _people = null;
    private int _cursor = -1;
    public PeopleEnum(Person[] list) {
        _people = list;
    }
    public bool MoveNext() {
        _cursor++;
        return (_cursor < _people.Length);
    }
    public void Reset() {
        _cursor = -1;
    }
    public object Current {
        get {
            try {
                return _people[_cursor];
            }
            catch (IndexOutOfRangeException) {
                throw new InvalidOperationException();
            }
        }
    }
}

PeopleEnum类,实现IEnumerator接口。

yield return迭代器实现

yield关键字向编译器指示它所在的方法是迭代器块,yield return返回一个迭代器的状态机。

public class ApplePhone {
    public string PhoneName { get; set; }
    public DateTime PublishedDate { get; set; }
}

ApplePhone类,包含手机名称和发布日期。

public class BestEnum {
    public static IEnumerable<ApplePhone> GetIPhones() {
        yield return new ApplePhone {
            PhoneName = "IPhone",
            PublishedDate = new DateTime(2007, 1, 9)
        };
        yield return new ApplePhone {
            PhoneName = "IPhone 3G",
            PublishedDate = new DateTime(2008, 6, 10)
        };
        yield return new ApplePhone {
            PhoneName = "IPhone 3GS",
            PublishedDate = new DateTime(2009, 6, 9)
        };
        yield return new ApplePhone {
            PhoneName = "IPhone 4",
            PublishedDate = new DateTime(2010, 6, 8)
        };
        //部分代码已省略
    }
}

BestEnum类,包含GetIPhones方法返回苹果手机信息的序列。

public class Program {
    protected const string LINE_BREAK =
        "---------------------------------------------";
    public static void Main(string[] args) {
        var peopleArray = new Person[]
        {
            new Person("John", "Smith"),
            new Person("Jim", "Johnson"),
            new Person("Sue", "Rabon")
        };
        var peopleList = new People(peopleArray);
        foreach(Person p in peopleList)
            Console.WriteLine(p.FirstName + " " + p.LastName);
        Console.WriteLine(LINE_BREAK);
        var iterator = peopleList.GetEnumerator();
        while(iterator.MoveNext()) {
            var person = iterator.Current as Person;
            Console.WriteLine(person.FirstName + " " + person.LastName);
        }
        Console.WriteLine(LINE_BREAK);
        foreach(var phone in BestEnum.GetIPhones()) {
            Console.WriteLine("[" + phone.PhoneName + "] was released in " +
                              phone.PublishedDate.ToString("yyyy-MM-dd") + "!");
        }
        Console.WriteLine(LINE_BREAK);
        Console.ReadKey();
    }
}

以上是调用方的代码,以下是这个案例的输出结果:

John Smith
Jim Johnson
Sue Rabon
---------------------------------------------
John Smith
Jim Johnson
Sue Rabon
---------------------------------------------
[IPhone] was released in 2007-01-09!
[IPhone 3G] was released in 2008-06-10!
[IPhone 3GS] was released in 2009-06-09!
[IPhone 4] was released in 2010-06-08!
[IPhone 4s] was released in 2011-10-04!
[IPhone 5] was released in 2012-09-13!
[IPhone 5S] was released in 2013-09-10!
[IPhone 5C] was released in 2013-09-10!
[IPhone 6] was released in 2014-09-10!
[IPhone 6 Plus] was released in 2014-09-10!
[IPhone 6s] was released in 2015-09-10!
[IPhone 6s Plus] was released in 2015-09-10!
[IPhone 7] was released in 2016-09-08!
[IPhone 7 Plus] was released in 2016-09-08!
[IPhone 8] was released in 2017-09-13!
[IPhone 8 Plus] was released in 2017-09-13!
[IPhone X] was released in 2017-09-13!
---------------------------------------------

总结

优点

1、迭代器模式使得访问一个聚合对象的内容而无需暴露它的内部表示,即迭代抽象;

2、迭代器模式为遍历不同的集合结构提供了一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作。


缺点

1、迭代器模式在遍历的同时更改迭代器所在的集合结构会导致出现异常。所以使用foreach语句只能在对集合进行遍历,不能在遍历的同时更改集合中的元素。


使用场景

1、系统需要访问一个聚合对象的内容而无需暴露它的内部表示;

2、系统需要支持对聚合对象的多种遍历;

3、系统需要为不同的聚合结构提供一个统一的接口。


相关文章
|
2月前
|
设计模式 Java 开发者
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
本教程详细讲解Kotlin语法,适合希望深入了解Kotlin的开发者。对于快速学习Kotlin的用户,推荐查看“简洁”系列教程。本文重点介绍迭代器模式,通过具体示例展示了如何在Kotlin中实现迭代器模式,包括使用Iterator、Iterable接口及重载iterator运算符的方法。
32 4
|
2月前
|
设计模式 Java Kotlin
Kotlin学习笔记 - 改良设计模式 - 迭代器模式
Kotlin学习笔记 - 改良设计模式 - 迭代器模式
29 2
|
2月前
|
设计模式 Java 开发者
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
本教程详细讲解了Kotlin中的迭代器模式,包括如何通过实现Iterator和Iterable接口以及重载iterator运算符来实现可遍历的自定义集合。示例展示了如何创建一个图书集类,并通过不同方式使其支持遍历操作,适合希望深入了解Kotlin迭代器模式的开发者。
29 3
|
23天前
|
设计模式 Java Kotlin
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
32 0
|
2月前
|
设计模式 Java Kotlin
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
33 1
|
2月前
|
设计模式 Java Kotlin
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
28 1
|
3月前
|
设计模式
设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)
这篇文章详细解释了工厂模式,包括简单工厂、工厂方法和抽象工厂三种类型。每种模式都通过代码示例展示了其应用场景和实现方法,并比较了它们之间的差异。简单工厂模式通过一个工厂类来创建各种产品;工厂方法模式通过定义一个创建对象的接口,由子类决定实例化哪个类;抽象工厂模式提供一个创建相关或依赖对象家族的接口,而不需要明确指定具体类。
设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)
|
3月前
|
设计模式 安全 Java
Java设计模式-迭代器模式(21)
Java设计模式-迭代器模式(21)
|
3月前
|
设计模式 Java
设计模式--适配器模式 Adapter Pattern
这篇文章介绍了适配器模式,包括其基本介绍、工作原理以及类适配器模式、对象适配器模式和接口适配器模式三种实现方式。
|
5月前
|
存储 NoSQL Go
iLogtail设计模式问题之迭代器模式是如何应用的
iLogtail设计模式问题之迭代器模式是如何应用的