1:主题拆解
①基本介绍
②客户与商品数据遍历
③迭代器模式的优缺点
④适用场景
⑤应有实例
2:基本介绍
提供一种方法访问一个容器对象中各个元素,而又不暴露该对象的内部细节。
迭代器模式的结构如下
①抽象容器
一般是一个接口,提供一个iterator()方法。
②具体容器
就是抽象容器的具体实现类,比如List接口的有序列表实现ArrayList,List接口的链表实现LinkList,Set接口的哈希列表的实现HashSet等。
③抽象迭代器
定义遍历元素所需要的方法,一般来说会有这么三个方法:取得第一个元素的方法first(),取得下一个元素的方法next(),判断是否遍历结束的方法isDone()(或者叫hasNext()),移出当前对象的方法remove(),
④迭代器实现
实现迭代器接口中定义的方法,完成集合的迭代。
3:客户与商品数据遍历
①定义数据实体
public class DataEntity
{
public int Id { get; set; }
public string Name { get; set; }
public int Price { get; set; }
}
②客户与商品实例类
public class CustomerMenu
{
private DataEntity[] _EntityList = new DataEntity[3];
public CustomerMenu()
{
this._EntityList[0] = new DataEntity()
{
Id = 1,
Name = "华为",
Price = 15
};
this._EntityList[1] = new DataEntity()
{
Id = 2,
Name = "小米",
Price = 10
};
this._EntityList[2] = new DataEntity()
{
Id = 3,
Name = "Apple",
Price = 8
};
}
public DataEntity[] GetEntity()
{
return this._EntityList;
}
public IIterator<DataEntity> GetIterator()
{
return new KFCMenuIterator(this);
}
}
public class ProductMenu
{
private List<DataEntity> _EntityList = new List<DataEntity>();
public ProductMenu()
{
this._EntityList.Add(new DataEntity()
{
Id = 1,
Name = "华为P40Pro",
Price = 15
});
this._EntityList.Add( new DataEntity()
{
Id = 2,
Name = "小米X Max",
Price = 10
});
this._EntityList.Add(new DataEntity()
{
Id = 3,
Name = "IPhone 13 Plus",
Price = 9
});
}
public List<DataEntity> GetEntity()
{
return this._EntityList;
}
public IIterator<DataEntity> GetIterator()
{
return new ProductMenuIterator(this);
}
}
③迭代器基类
public interface IIterator<T>
{
T Current { get; }
bool MoveNext();
void Reset();
}
④新的集合实现IIterator接口
public class CustomerMenuIterator : IIterator<DataEntity>
{
private DataEntity[] _FoodList = null;
public CustomerMenuIterator(CustomerMenu menu)
{
this._FoodList = menu.GetEntity();
}
private int _Index = -1;
public DataEntity Current
{
get
{
return this._FoodList[_Index];
}
}
public bool MoveNext()
{
return this._FoodList.Length > ++this._Index;
}
public void Reset()
{
this._Index = -1;
}
}
public class ProductMenuIterator : IIterator<DataEntity>
{
private List<DataEntity> _FoodList = null;
public ProductMenuIterator(ProductMenu menu)
{
this._FoodList = menu.GetEntity();
}
private int _Index = -1;
public DataEntity Current
{
get
{
return this._FoodList[_Index];
}
}
public bool MoveNext()
{
return this._FoodList.Count > ++this._Index;
}
public void Reset()
{
this._Index = -1;
}
}
⑤上端调用
CustomerMenu customerMenu = new CustomerMenu();
DataEntity[] foods = customerMenu.GetEntity();
IIterator<DataEntity> iteratorCustomer = customerMenu.GetIterator();
while (iteratorCustomer.MoveNext())
{
DataEntity itemCustomer = iteratorCustomer.Current;
Console.WriteLine("{0} {1} {2}", itemCustomer.Id, itemCustomer.Name, itemCustomer.Price);
}
ProductMenu productMenu = new ProductMenu();
IIterator<DataEntity> iteratorProduct = productMenu.GetIterator();
while (iteratorProduct.MoveNext())
{
DataEntity itemProduct = iteratorProduct.Current;
Console.WriteLine("{0} {1} {2}", itemProduct.Id, itemProduct.Name, itemProduct.Price);
}
⑥执行结果
4:迭代器模式的优缺点
1:优点
①多种遍历方式
支持以不同方式遍历聚合对象,在同一聚合对象上可以定义多种遍历方法,只需要用一个不同的聚合器替换原来的迭代器即可改变遍历算法。
②简化聚合类
原有的聚合对象不需要再自行提供数据遍历方法。
②满足OCP
由于引入了抽象层,增加新的聚合类以及迭代器类都很方便,无须修改源码。
2:缺点
①复杂度增加
迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,增加了复杂性。
②抽象迭代器较难设计
考虑到以后的扩展,抽象迭代器的设计难度可能非常大,比如JDK的内置迭代器Iterator就无法实现逆向遍历,设计一个考虑全面的抽象迭代器并不是一件容易的事。
5:适用场景
①访问一个聚合对象的内容而无须暴露它的内部表示。将聚合对象的访问与内部数据存储分离,使得访问聚合对象时无须了解内部实现细节。
②需要为一个聚合对象提供多种遍历方式。
③为遍历不同的聚合结构提供一个统一的接口,在该接口的实现类为不同的聚合结构提供不同的遍历方式,而客户端可以一致性地操作该接口。
6:应用实例
List
Arrary
IEnumerable