老生常谈:迭代器模式
有很多方法可以把对象堆起来成为一个集合。你可以把它们放进数组,堆栈,列表,或者是散列表中,这是你的自由。
迭代器模式定义:提供一个方法顺序访问一个聚合对象中的各个元素,而又不暴露它内部的表示.迭代器模式把在元素之间的游走的责任交给迭代器,而不是聚合对象,这不仅让聚合的接口和实现变得更简洁,也可以让聚合更加专注在它所应该专注的事情上面,而不用去理会遍历的事情。
迭代器类图:
现在引用《Head First》原文来说明迭代器模式的用法。
原本两家餐厅都是有自己的菜单实现方法,对象村餐厅的菜单用数组实现,而煎饼物的则应用List<>来实现,现在合并了,毕然在菜单上实现方法上要有统一性.两家餐厅都同意这种做法,但是他们又不想改变自己菜单的实现方法,因为在他们各自的餐厅中都有很多地方依赖于自己菜单的实现方法.那么还能不能进行统一呢?答案是肯定的.他们有一个共同的特点:就是都是针对聚合对象操作,无论是散列表,堆栈,List<>,等等,两家菜单都要有遍历自己菜单的功能。这里都引入了迭代器模式。
统一的迭代器接口:
这里用了泛型接口,因为返回的具体实例有不同。
我们知道list<>和数组在做遍历操作的时候方法是不同的。要想实现两家餐厅菜单的统一,为此两家餐厅在菜单的实现上面可以通过面积接口编程来实现,不要通过具体实现。
1: 对象村餐厅的迭代器:它是针对数组实现
2:煎饼店的迭代器:它是用List<>实现
1:对象村菜单实现:
2:煎饼店菜单实现:
3:菜单项具体内容:为了简化代码,在这就写了菜单项的名称,其它的省略了。
4:服务员调用代码:有了菜单还得要有服务的服务,服务员的责任就是打印出来两家餐厅的所在菜单项供客人点餐。
5:client调用:简单的打印出了两家餐厅的所有菜单项的名称。
总结:迭代器模式针对多种聚合对象操作的实现特别有帮助,可以将多种不同的聚合对象统一起来。
迭代器模式定义:提供一个方法顺序访问一个聚合对象中的各个元素,而又不暴露它内部的表示.迭代器模式把在元素之间的游走的责任交给迭代器,而不是聚合对象,这不仅让聚合的接口和实现变得更简洁,也可以让聚合更加专注在它所应该专注的事情上面,而不用去理会遍历的事情。
迭代器类图:
现在引用《Head First》原文来说明迭代器模式的用法。
原本两家餐厅都是有自己的菜单实现方法,对象村餐厅的菜单用数组实现,而煎饼物的则应用List<>来实现,现在合并了,毕然在菜单上实现方法上要有统一性.两家餐厅都同意这种做法,但是他们又不想改变自己菜单的实现方法,因为在他们各自的餐厅中都有很多地方依赖于自己菜单的实现方法.那么还能不能进行统一呢?答案是肯定的.他们有一个共同的特点:就是都是针对聚合对象操作,无论是散列表,堆栈,List<>,等等,两家菜单都要有遍历自己菜单的功能。这里都引入了迭代器模式。
统一的迭代器接口:
public interface Iterator<T>
{
//判断是否有下一个
bool hasNext();
//取得下一个菜单项
T next();
}
{
//判断是否有下一个
bool hasNext();
//取得下一个菜单项
T next();
}
这里用了泛型接口,因为返回的具体实例有不同。
我们知道list<>和数组在做遍历操作的时候方法是不同的。要想实现两家餐厅菜单的统一,为此两家餐厅在菜单的实现上面可以通过面积接口编程来实现,不要通过具体实现。
1: 对象村餐厅的迭代器:它是针对数组实现
public class DinerMenuIterator<T> : Iterator<BLL.IteratorTest.MenuItem>
{
MenuItem[] items;
int position = 0;//当前位置
//判断是否有下一个
public bool hasNext()
{
if (position >= items.Length || items[position] == null)
{
return false;
}
else
{
return true;
}
}
//取得下一个菜单项
public MenuItem next()
{
MenuItem menuItem = items[position];
position += 1;
return menuItem;
}
public DinerMenuIterator(MenuItem[] items)
{
this.items = items;
}
}
{
MenuItem[] items;
int position = 0;//当前位置
//判断是否有下一个
public bool hasNext()
{
if (position >= items.Length || items[position] == null)
{
return false;
}
else
{
return true;
}
}
//取得下一个菜单项
public MenuItem next()
{
MenuItem menuItem = items[position];
position += 1;
return menuItem;
}
public DinerMenuIterator(MenuItem[] items)
{
this.items = items;
}
}
2:煎饼店的迭代器:它是用List<>实现
public class PancakeHouseMenuIterator<T> : Iterator<BLL.IteratorTest.MenuItem>
{
List<MenuItem > items;
int position = 0;//当前位置
//判断是否有下一个
public bool hasNext()
{
if (position >= items.Count || items[position] == null)
{
return false;
}
else
{
return true;
}
}
//取得下一个菜单项
public MenuItem next()
{
MenuItem menuItem = items[position];
position += 1;
return menuItem;
}
public PancakeHouseMenuIterator(List<MenuItem> items)
{
this.items = items;
}
}
{
List<MenuItem > items;
int position = 0;//当前位置
//判断是否有下一个
public bool hasNext()
{
if (position >= items.Count || items[position] == null)
{
return false;
}
else
{
return true;
}
}
//取得下一个菜单项
public MenuItem next()
{
MenuItem menuItem = items[position];
position += 1;
return menuItem;
}
public PancakeHouseMenuIterator(List<MenuItem> items)
{
this.items = items;
}
}
1:对象村菜单实现:
public class DinerMenu
{
MenuItem[] menuItems;
public DinerMenu()
{
//菜单中最多放11个菜单项
menuItems = new MenuItem[10];
addItem("DinerMenu:eag");
}
/// <summary>
/// 增加菜单项
/// </summary>
/// <param name="name"></param>
public void addItem(string name)
{
MenuItem _menuItem = new MenuItem(name);
//为了简化代码在这就加入一个菜单项
menuItems[0] = _menuItem;
}
public Iterator<MenuItem> createIterator()
{
return new DinerMenuIterator<MenuItem >(menuItems );
}
}
{
MenuItem[] menuItems;
public DinerMenu()
{
//菜单中最多放11个菜单项
menuItems = new MenuItem[10];
addItem("DinerMenu:eag");
}
/// <summary>
/// 增加菜单项
/// </summary>
/// <param name="name"></param>
public void addItem(string name)
{
MenuItem _menuItem = new MenuItem(name);
//为了简化代码在这就加入一个菜单项
menuItems[0] = _menuItem;
}
public Iterator<MenuItem> createIterator()
{
return new DinerMenuIterator<MenuItem >(menuItems );
}
}
2:煎饼店菜单实现:
public class PancakeHouseMenu
{
List<MenuItem > _menuItems;
public PancakeHouseMenu()
{
addItem("PancakeHouseMenu:eag");
}
/// <summary>
/// 增加菜单项
/// </summary>
/// <param name="name"></param>
public void addItem(string name)
{
MenuItem _menuItem = new MenuItem(name);
_menuItems = new List<MenuItem>();
_menuItems.Add(_menuItem);
}
public Iterator<MenuItem> createIterator()
{
return new PancakeHouseMenuIterator<MenuItem>(_menuItems);
}
}
{
List<MenuItem > _menuItems;
public PancakeHouseMenu()
{
addItem("PancakeHouseMenu:eag");
}
/// <summary>
/// 增加菜单项
/// </summary>
/// <param name="name"></param>
public void addItem(string name)
{
MenuItem _menuItem = new MenuItem(name);
_menuItems = new List<MenuItem>();
_menuItems.Add(_menuItem);
}
public Iterator<MenuItem> createIterator()
{
return new PancakeHouseMenuIterator<MenuItem>(_menuItems);
}
}
3:菜单项具体内容:为了简化代码,在这就写了菜单项的名称,其它的省略了。
public class MenuItem
{
//菜单具体内容名称
string _name;
public MenuItem(string name)
{
this._name = name;
}
/// <summary>
/// 菜单项名称
/// </summary>
public string name
{
get { return this._name; }
set { this._name = value; }
}
}
{
//菜单具体内容名称
string _name;
public MenuItem(string name)
{
this._name = name;
}
/// <summary>
/// 菜单项名称
/// </summary>
public string name
{
get { return this._name; }
set { this._name = value; }
}
}
4:服务员调用代码:有了菜单还得要有服务的服务,服务员的责任就是打印出来两家餐厅的所在菜单项供客人点餐。
public class Waitress
{
PancakeHouseMenu _PancakeHouseMenu;
DinerMenu _DinerMenu;
public Waitress(PancakeHouseMenu pancakeHouseMenu, DinerMenu dinerMenu)
{
this._PancakeHouseMenu = pancakeHouseMenu;
this._DinerMenu = dinerMenu;
}
/// <summary>
/// 返回菜单项的内容
/// </summary>
/// <param name="iterator"></param>
/// <returns></returns>
public string printMenu(Iterator<MenuItem> iterator)
{
string sContent = "";
while (iterator.hasNext())
{
MenuItem menuItem = (MenuItem)iterator.next();
sContent += menuItem.name+"\n";
}
return sContent;
}
public string printMenu()
{
//对象村餐厅菜单内容
Iterator<MenuItem > dinerMenuIterator = _DinerMenu.createIterator();
//对象村煎饼店餐厅菜单内容
Iterator<MenuItem> pancakeHouseMenuIterator = _PancakeHouseMenu .createIterator();
string s = "";
s +="对象村餐厅菜单内容:"+printMenu(dinerMenuIterator)+"\n";
s += "对象村煎饼店餐厅菜单内容:" + printMenu(pancakeHouseMenuIterator );
return s;
}
}
{
PancakeHouseMenu _PancakeHouseMenu;
DinerMenu _DinerMenu;
public Waitress(PancakeHouseMenu pancakeHouseMenu, DinerMenu dinerMenu)
{
this._PancakeHouseMenu = pancakeHouseMenu;
this._DinerMenu = dinerMenu;
}
/// <summary>
/// 返回菜单项的内容
/// </summary>
/// <param name="iterator"></param>
/// <returns></returns>
public string printMenu(Iterator<MenuItem> iterator)
{
string sContent = "";
while (iterator.hasNext())
{
MenuItem menuItem = (MenuItem)iterator.next();
sContent += menuItem.name+"\n";
}
return sContent;
}
public string printMenu()
{
//对象村餐厅菜单内容
Iterator<MenuItem > dinerMenuIterator = _DinerMenu.createIterator();
//对象村煎饼店餐厅菜单内容
Iterator<MenuItem> pancakeHouseMenuIterator = _PancakeHouseMenu .createIterator();
string s = "";
s +="对象村餐厅菜单内容:"+printMenu(dinerMenuIterator)+"\n";
s += "对象村煎饼店餐厅菜单内容:" + printMenu(pancakeHouseMenuIterator );
return s;
}
}
5:client调用:简单的打印出了两家餐厅的所有菜单项的名称。
PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
DinerMenu dinerMenu = new DinerMenu();
Waitress waitress = new Waitress(pancakeHouseMenu, dinerMenu);
string s = waitress.printMenu();
this.Label1.Text = s;
DinerMenu dinerMenu = new DinerMenu();
Waitress waitress = new Waitress(pancakeHouseMenu, dinerMenu);
string s = waitress.printMenu();
this.Label1.Text = s;
总结:迭代器模式针对多种聚合对象操作的实现特别有帮助,可以将多种不同的聚合对象统一起来。