• 17.Iterator迭代器(行为型模式)


    一:动机(Motivation)

    <1>在面向对象的软件设计中,我们经常会遇到一类集合对象,这类集合对象的内部结构可能有着各种各样的实现,但是归结起来,无非有两点是需要我们去关心的:一是集合内部的数据存储结构,二是遍历集合内部的数据。面向对象设计原则中有一条是类的单一职责原则,所以我们要尽可能的去分解这些职责,用不同的类去承担不同的职责。

    <2>Iterator模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明的访问集合内部的数据。

    二:意图(Intent)

    提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。
    ——《设计模式》GoF

    三:结构(Structure)

    在这里插入图片描述

    四:结构详解

    在这里插入图片描述

    五:生活中的例子

    <1>在公交车上,售票员不管上来的是什么人,总会要求每个人都来买票。
    <2>不管乘客是什么,售票员的做法都是相同的:
    从第一个开始
    当前是谁
    下一个
    是否结束

    六:实现

    namespace Test
    {
        /// 
        /// 迭代器,用来执行迭代操作
        /// 
        public abstract class Iterator
        {
            public abstract object First();  //第一个
            public abstract object CurrentItem();  //当前这一个
            public abstract object Next();  //下一个
            public abstract bool IsDone();  //结束了没有?
        }
    
        /// 
        /// 聚合类,代表一个可迭代的集合
        /// 
        public abstract class Aggregate
        {
            public abstract Iterator CreateIterator();  //返回一个迭代器
        }
    
        /// 
        /// ConcreteAggregate  具体的聚合类
        /// 
        public class 车上的乘客 : Aggregate
        {
            private System.Collections.ArrayList al = new System.Collections.ArrayList();
    
            public override Iterator CreateIterator()
            {
                return new ConcreteIterator(this);
            }
    
            public void 上车(string 乘客姓名)
            {
                this.al.Add(乘客姓名);
            }
    
            public string this[int index]
            {
                get
                {
                    return this.al[index].ToString();
                }
            }
    
            public int 数量
            {
                get
                {
                    return this.al.Count;
                }
            }
        }
    
        /// 
        /// ConcreteIterator  具体的迭代器
        /// 
        public class ConcreteIterator : Iterator
        {
            private 车上的乘客 _乘客们 = null;
    
            private int 当前第几个 = 0;
    
            public ConcreteIterator(车上的乘客 乘客)
            {
                this._乘客们 = 乘客;
            }
    
            public override object First()
            {
                if (this._乘客们.数量 > 0)
                {
                    this.当前第几个 = 0;
                    return this._乘客们[0];
                }
                else
                {
                    return null;
                }
            }
    
            public override object CurrentItem()
            {
                return this._乘客们[当前第几个];
            }
    
            public override object Next()
            {
                this.当前第几个++;
                if (this.当前第几个 < this._乘客们.数量)
                {
                    return this._乘客们[当前第几个];
                }
                else
                {
                    return null;
                }
            }
    
            public override bool IsDone()
            {
                return this.当前第几个 >= this._乘客们.数量;
            }
        }
    
        internal class Program
        {
            static void Main(string[] args)
            {
                车上的乘客 隧道六线 = new 车上的乘客();
                隧道六线.上车("张三");
                隧道六线.上车("李四");
                隧道六线.上车("王五");
                隧道六线.上车("赵六");
    
                Iterator iterator = 隧道六线.CreateIterator();
    
                while (!iterator.IsDone())
                {
                    Console.WriteLine("{0},请你买票,谢谢!", iterator.CurrentItem());
                    iterator.Next();
                }
                Console.ReadLine();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127

    在这里插入图片描述

    七:适用性

    <1>访问一个聚合对象的内容而无需暴露它的内部表示。
    <2>支持对聚合对象的多种遍历。
    <3>为遍历不同的聚合结构提供一个统一的接口(即,支持多态迭代)。

    namespace Test
    {
        /// 
        /// 聚合对象(集合)
        /// 
        public abstract class Aggregate
        {
            public abstract Iterator CreateIterator();
        }
    
        /// 
        /// 迭代器:能遍历一个集合的遍历行为
        /// 
        public abstract class Iterator
        {
            public abstract object First();
            public abstract void Next();
            public abstract object Current();
            public abstract bool IsDone
            {
                get;
            }
        }
    
        /// 
        /// 一年级
        /// 
        public class FirstGrade : Aggregate
        {
            public override Iterator CreateIterator()
            {
                //return new FirstGradeAsceIterator(this);
                return new FirstGradeDeAsceIterator(this);
            }
    
            private List<Student> students = new List<Student>();
            public void AddStudent(Student student)
            {
                this.students.Add(student);
            }
    
            public int StudentsCount
            {
                get { return this.students.Count; }
            }
    
            public Student this[int index]
            {
                get { return this.students[index]; }
            }
        }
    
        public class Student
        {
            public Student(string name)
            {
                this.Name = name;
            }
    
            public string Name { get; set; }
            public override string ToString()
            {
                return this.Name;
            }
        }
    
        /// 
        /// 按照升序迭代
        /// 
        public class FirstGradeAsceIterator : Iterator
        {
            /// 
            /// 关联到需要迭代的一年级班级(集合)
            /// 
            private FirstGrade? myClass = null;
    
            /// 
            /// 对班级的依赖
            /// 
            /// 
            public FirstGradeAsceIterator(FirstGrade myClassToIterator)
            {
                this.myClass = myClassToIterator;
            }
    
            private int currentIndex = 0;
    
            public override object Current()
            {
                return this.myClass[this.currentIndex];
            }
    
            public override object First()
            {
                return this.myClass[0];
            }
    
            public override void Next()
            {
                this.currentIndex++;
            }
    
            public override bool IsDone
            {
                get
                {
                    return this.currentIndex == this.myClass.StudentsCount;
                }
            }
        }
    
        /// 
        /// 按照降序迭代
        /// 
        public class FirstGradeDeAsceIterator : Iterator
        {
            /// 
            /// 关联到需要迭代的一年级班级(集合)
            /// 
            private FirstGrade? myClass = null;
    
            private int currentIndex;
    
            /// 
            /// 对班级的依赖
            /// 
            /// 
            public FirstGradeDeAsceIterator(FirstGrade myClassToIterator)
            {
                this.myClass = myClassToIterator;
                currentIndex = myClass.StudentsCount - 1;
            }
    
            public override object Current()
            {
                return this.myClass[this.currentIndex];
            }
    
            public override object First()
            {
                return this.myClass[myClass.StudentsCount - 1];
            }
    
            public override void Next()
            {
                this.currentIndex--;
            }
    
            public override bool IsDone
            {
                get
                {
                    return this.currentIndex == -1;
                }
            }
        }
    
        internal class Program
        {
            static void Main(string[] args)
            {
                FirstGrade firstGrade = new FirstGrade();
                firstGrade.AddStudent(new Student("张三"));
                firstGrade.AddStudent(new Student("李四"));
                firstGrade.AddStudent(new Student("王五"));
    
                Iterator iterator = (firstGrade as Aggregate).CreateIterator();
                while (!iterator.IsDone)
                {
                    object current = iterator.Current();
                    Console.WriteLine(current);
                    iterator.Next();
                }
                Console.ReadLine();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    namespace Test
    {
        /// 
        /// 聚合对象(集合)
        /// 
        public abstract class Aggregate
        {
            public abstract Iterator CreateIterator();
        }
    
        /// 
        /// 迭代器:能遍历一个集合的遍历行为
        /// 
        public abstract class Iterator
        {
            public abstract object First();
            public abstract void Next();
            public abstract object Current();
            public abstract bool IsDone
            {
                get;
            }
        }
    
        /// 
        /// 一年级
        /// 
        public class FirstGrade : Aggregate
        {
            public override Iterator CreateIterator()
            {
                return new FirstGradeAsceIterator(this);
                //return new FirstGradeDeAsceIterator(this);
            }
    
            private List<Student> students = new List<Student>();
            public void AddStudent(Student student)
            {
                this.students.Add(student);
            }
    
            /// 
            /// 按照升序迭代
            /// 
            private class FirstGradeAsceIterator : Iterator
            {
                /// 
                /// 关联到需要迭代的一年级班级(集合)
                /// 
                private FirstGrade? myClass = null;
    
                /// 
                /// 对班级的依赖
                /// 
                /// 
                public FirstGradeAsceIterator(FirstGrade myClassToIterator)
                {
                    this.myClass = myClassToIterator;
                }
    
                private int currentIndex = 0;
    
                public override object Current()
                {
                    return this.myClass.students[this.currentIndex];
                }
    
                public override object First()
                {
                    return this.myClass.students[0];
                }
    
                public override void Next()
                {
                    this.currentIndex++;
                }
    
                public override bool IsDone
                {
                    get
                    {
                        return this.currentIndex == this.myClass.students.Count;
                    }
                }
            }
    
            /// 
            /// 按照降序迭代
            /// 
            private class FirstGradeDeAsceIterator : Iterator
            {
                /// 
                /// 关联到需要迭代的一年级班级(集合)
                /// 
                private FirstGrade? myClass = null;
    
                private int currentIndex;
    
                /// 
                /// 对班级的依赖
                /// 
                /// 
                public FirstGradeDeAsceIterator(FirstGrade myClassToIterator)
                {
                    this.myClass = myClassToIterator;
                    currentIndex = myClass.students.Count - 1;
                }
    
                public override object Current()
                {
                    return this.myClass.students[this.currentIndex];
                }
    
                public override object First()
                {
                    return this.myClass.students[myClass.students.Count - 1];
                }
    
                public override void Next()
                {
                    this.currentIndex--;
                }
    
                public override bool IsDone
                {
                    get
                    {
                        return this.currentIndex == -1;
                    }
                }
            }
        }
    
        public class Student
        {
            public Student(string name)
            {
                this.Name = name;
            }
    
            public string Name { get; set; }
            public override string ToString()
            {
                return this.Name;
            }
        }
    
        internal class Program
        {
            static void Main(string[] args)
            {
                FirstGrade firstGrade = new FirstGrade();
                firstGrade.AddStudent(new Student("张三"));
                firstGrade.AddStudent(new Student("李四"));
                firstGrade.AddStudent(new Student("王五"));
    
                Iterator iterator = (firstGrade as Aggregate).CreateIterator();
                while (!iterator.IsDone)
                {
                    object current = iterator.Current();
                    Console.WriteLine(current);
                    iterator.Next();
                }
                Console.ReadLine();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    using System.Collections;
    using System.Collections.Generic;
    
    namespace Test
    {
        public class 车上的乘客NET : System.Collections.IEnumerable
        {
            private System.Collections.ArrayList al = new System.Collections.ArrayList();
            public void 上车(string 乘客姓名)
            {
                this.al.Add(乘客姓名);
            }
            public string this[int index]
            {
                get { return this.al[index].ToString(); }
            }
            public int 数量
            {
                get { return this.al.Count; }
            }
            #region IEnumerable 成员
            public System.Collections.IEnumerator GetEnumerator()
            {
                return new ConcreteIteratorNET(this);
            }
            #endregion
        }
    
        public class 车上的乘客NET2 : System.Collections.IEnumerable
        {
            private System.Collections.ArrayList al = new System.Collections.ArrayList();
    
            public void 上车(string 乘客姓名)
            {
                this.al.Add(乘客姓名);
            }
            #region IEnumerable 成员
    
            public System.Collections.IEnumerator GetEnumerator()
            {
                foreach (object var in this.al)
                {
                    yield return var;
                }
            }
            #endregion
        }
    
        public class ConcreteIteratorNET : System.Collections.IEnumerator
        {
            private 车上的乘客NET _乘客们 = null;
            private int 当前第几个 = -1;
            public ConcreteIteratorNET(车上的乘客NET 乘客)
            {
                this._乘客们 = 乘客;
            }
            #region IEnumerator 成员
            public object Current
            {
                get { return this._乘客们[当前第几个]; }
            }
            public bool MoveNext()
            {
                this.当前第几个++;
                return this.当前第几个 < this._乘客们.数量;
            }
            public void Reset()
            {
                this.当前第几个 = -1;
            }
            #endregion
        }
    
        internal class Program
        {
            static void Main(string[] args)
            {
                车上的乘客NET 隧道六线 = new 车上的乘客NET();
                隧道六线.上车("张三");
                隧道六线.上车("李四");
                隧道六线.上车("王五");
                隧道六线.上车("赵六");
                System.Collections.IEnumerator iterator = 隧道六线.GetEnumerator();
    
                while (iterator.MoveNext())
                {
                    Console.WriteLine("{0},请你买票,谢谢!", iterator.Current);
                }
    
                Console.ReadLine();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93

    八:总结

    <1>迭代抽象:访问一个聚合对象的内容而无需暴露它的内部表示。
    <2>迭代多态:为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作。
    <3>迭代器的健壮性考虑:遍历的同时更改迭代器所在的集合结构,会导致问题。

  • 相关阅读:
    案例分享|智慧化的西部机场
    西门子系列PLC与C#winform通信类
    【CMN】Components组件汇总
    ant的javac任务的相关属性配置
    图的最小生成树算法(图解+代码)| 学不会来看我系列
    DataHub元数据采集
    Linux:环境变量、地址空间
    Metabase学习教程:视图-8
    神经网络基础
    T31开发笔记:GPIO控制
  • 原文地址:https://blog.csdn.net/zzyzxb/article/details/126662049