zoukankan      html  css  js  c++  java
  • 迭代器模式(Iterator Pattern)

    模式定义

    提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该对象的内部表示。

    UML类图

    • 抽象迭代角色(Iterator) 负责定义访问和遍历元素的接口(如Next()下一个元素,IsDone()集合是否变量完,CurrentItem()当前元素等)
    • 具体迭代角色(Concrete Iterator) 关联具体聚合角色,实现迭代器接口,并需要私有字段记录遍历中的当前位置。
    • 聚集(Aggregate) 依赖迭代器角色,定义获得迭代器的接口。
    • 具体聚集(Concrete Aggregate) 实现聚合角色接口,私有字段:需要遍历的集合;共有方法:集合的数量和集合的索引

    代码结构

    	public static class IteratorApp
    	{
    		public static void Run()
    		{
    			ConcreteAggregate a = new ConcreteAggregate();
    
    			a[0] = "Item A";
    			a[1] = "Item B";
    			a[2] = "Item C";
    			a[3] = "Item D";
    
    			Iterator i = a.CreateIterator();
    
    			Console.WriteLine("Iterating over collection");
    
    			object item = i.Firest();
    			while (item != null)
    			{
    				Console.WriteLine(item);
    				item = i.Next();
    			}
    		}
    	}
    
    	abstract class Aggregate
    	{
    		public abstract Iterator CreateIterator();
    	}
    
    	class ConcreteAggregate : Aggregate
    	{
    		private ArrayList _items = new ArrayList();
    
    		public override Iterator CreateIterator()
    		{
    			return new ConcreteIterator(this);
    		}
    
    		public int Count
    		{
    			get { return _items.Count; }
    		}
    
    		public object this[int index]
    		{
    			get { return _items[index]; }
    			set { _items.Insert(index, value); }
    		}
    
    	}
    
    	abstract class Iterator
    	{
    		public abstract object Firest();
    		public abstract object Next();
    		public abstract bool IsDone();
    		public abstract object CurrentItem();
    	}
    
    	class ConcreteIterator : Iterator
    	{
    		private ConcreteAggregate _aggregate;
    		private int _current = 0;
    
    		public ConcreteIterator(ConcreteAggregate aggregate)
    		{
    			this._aggregate = aggregate;
    		}
    
    		public override object CurrentItem()
    		{
    			return _aggregate[_current];
    		}
    
    		public override object Firest()
    		{
    			return _aggregate[0];
    		}
    
    		public override bool IsDone()
    		{
    			return _current >= _aggregate.Count;
    		}
    
    		public override object Next()
    		{
    			object ret = null;
    			if (_current < _aggregate.Count - 1)
    			{
    				ret = _aggregate[++_current];
    			}
    
    			return ret;
    		}
    	}
    

    情景案例

    迭代器这种模式比较常见,主要是遍历集合。在C#中实现IEnumerable IEnumerable<out T>接口的都是可遍历的集合,而且可以通过语法糖foreach遍历。

    	public static class IteratorRealWorld
    	{
    		public static void RunApp()
    		{
    			Friend friend = new Friend();
    			FriendCollection friendcollection = friend.GetAllFriends();
    			foreach (Friend f in friendcollection)
    			{
    				Console.WriteLine(f.Name);
    			}
    		}
    	}
    
    	public class Friend
    	{
    		public string Name { get; set; }
    		public FriendCollection GetAllFriends()
    		{
    			return new FriendCollection(new Friend[]
    			{
    				new Friend(){Name ="关羽"},
    				new Friend(){Name ="张飞"},
    				new Friend(){Name ="赵云"},
    				new Friend(){Name ="黄忠"},
    				new Friend(){Name ="马超"}
    			});
    		}
    	}
    
    	public class FriendCollection : IEnumerable<Friend>
    	{
    		private Friend[] _friendArray;
    
    		public FriendCollection(Friend[] friend)
    		{
    			this._friendArray = friend;
    		}
    		public Friend this[int index]
    		{
    			get { return _friendArray[index]; }
    		}
    		public int Count
    		{
    			get { return _friendArray.Length; }
    		}
    
    		public IEnumerator<Friend> GetEnumerator()
    		{
    			return new FriendIterator(this);
    		}
    
    		IEnumerator IEnumerable.GetEnumerator()
    		{
    			return new FriendIterator(this);
    		}
    		//为内部类
    		public class FriendIterator : IEnumerator<Friend>
    		{
    			private readonly FriendCollection friends;
    			private int index;
    
    			public FriendIterator(FriendCollection friends)
    			{
    				this.friends = friends;
    				index = -1;
    			}
    
    			public Friend Current
    			{
    				get { return this.friends[index]; }
    			}
    
    			public void Dispose()
    			{
    			}
    
    			object IEnumerator.Current
    			{
    				get { return this.friends[index]; }
    			}
    
    			public bool MoveNext()
    			{
    				index++;
    				if (index >= friends.Count)
    				{
    					return false;
    				}
    				else
    				{
    					return true;
    				}
    			}
    
    			public void Reset()
    			{
    				index = -1;
    			}
    		}
    	}
    
  • 相关阅读:
    Cocos2d-x 3.0 beta 中加入附加项目,解决无法打开包括文件:“extensions/ExtensionMacros.h”: No such file or directory”
    C、Shell、Perl基于Tomcat开发CGI程序环境配置
    Windows机器配置启动加载器的高级选项后,机器出现蓝屏,无法RDP
    Linux由于物理节点故障导致的异常重启-Case1
    Azure经典虚拟机(Windows)如何监测单个磁盘的使用空间
    ARM VM安装Linux Diagnostic 2.3扩展
    rsyslog服务日志报错分析1
    登陆Linux服务器时触发邮件提醒
    部署Azure Log Analytics
    获取指定订阅下所有Azure ARM虚拟机配置(CPU核数,内存大小,磁盘信息)的使用情况
  • 原文地址:https://www.cnblogs.com/LoveTomato/p/8459749.html
Copyright © 2011-2022 走看看