您的位置:首页 > 其它

迭代器模式(Iterator Pattern)

2017-04-13 10:26 429 查看
 迭代器模式:让客户遍历你的对象而又无法窥视你存储对象的方式

场景:又一个早餐菜单和一个午餐菜单,使用迭代器模式将两个菜单打印出来。

//菜单创建迭代器的接口

//类似工厂模式,子类需要实现创建枚举对象的方法
public interface Menu
{
IEnumerator createIterator();
}
//菜单子项

public class MenuItem
{
string name;
string description;
bool vegetarian;
double price;

public MenuItem(string name, string description, bool vegetarian, double price)
{
this.name = name;
this.description = description;
this.vegetarian = vegetarian;
this.price = price;
}

public string getName()
{
return name;
}

public string getDescription()
{
return description;
}

public double getPrice()
{
return price;
}

public bool isVegetarian()
{
return vegetarian;
}
}

//早餐菜单
public class PancakeHouseMenu :Menu
{
List<MenuItem> menuItems;
public PancakeHouseMenu()
{
menuItems = new List<MenuItem>();

addItem("K&B's薄煎饼早餐", "薄煎饼、氢弹、吐司", true, 2.99);

addItem("薄煎饼早餐例餐", "薄煎饼带煎蛋、香肠", false, 2.99);

addItem("蓝莓薄煎饼","薄煎饼、新鲜蓝莓、蓝莓糖浆",true,3.49);

addItem("松饼", "松饼,可以选择蓝莓或草莓", true, 3.59);
}

public void addItem(string name, string description, bool vegetarian, double price)
{
MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
menuItems.Add(menuItem);
}

public List<MenuItem> getMenuItems()
{
return menuItems;
}
//早餐菜单在LIST中,List本身支持获取枚举对象
public IEnumerator createIterator()
{
return menuItems.GetEnumerator();
}
}//午餐菜单
public class DinerMenu : Menu, IEnumerator
{
const int MAX_ITEMS = 4;
int numberOfItems = 0;
MenuItem[] menuItems;
int position = -1;

public DinerMenu()
{
menuItems = new MenuItem[MAX_ITEMS];

addItem("素食BLT", "(煎)培根、生菜&西红柿放在麦皮面包上",true,2.99);

addItem("BLT", "培根、生菜&西红柿", true, 2.99);

}

public void addItem(string name, string description, bool vegetarian, double price)
{
MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
if (numberOfItems >= MAX_ITEMS)
{
Console.WriteLine("对不起,菜单已经满了,不允许增加菜单了!");
}
else
{
menuItems[numberOfItems] = menuItem;
numberOfItems++;
}
}

public MenuItem[] getMenuItems()
{
return menuItems;
}

public object Current
{
get
{
if (position < numberOfItems)
return menuItems[position];
else
return null;
}
}

public bool MoveNext()
{
position++;
if (position < numberOfItems)
{
return true;
}
else
{
return false;
}

}

public void Reset()
{
position = 0;
}
//午餐继承并实现了IEnumerator的接口,自身便包含了枚举对象
public IEnumerator createIterator()
{
return this;
}

}//服务员输出菜单
public class Waitress
{
Menu pancakeHouseMenu;
Menu dinerMenu;

public Waitress(Menu pancakeHouseMenu, Menu dinerMenu)
{
this.pancakeHouseMenu = pancakeHouseMenu;
this.dinerMenu = dinerMenu;
}

public void printMenu()
{
IEnumerator pancakeIterator = pancakeHouseMenu.createIterator();
IEnumerator dinerIterator = dinerMenu.createIterator();
Console.WriteLine("MENU\n----\nBREAKFAST");
printMenu(pancakeIterator);
Console.WriteLine("\nLUNCH");
printMenu(dinerIterator);
}
//利用C#对枚举的支持进行遍历
private void printMenu(IEnumerator iEnumerator)
{
while (iEnumerator.MoveNext())
{
if (iEnumerator.Current != null)
{
MenuItem menuItem = (MenuItem)iEnumerator.Current;
Console.Write(menuItem.getName() + ", ");
Console.Write(menuItem.getPrice().ToString() + " -- ");
Console.WriteLine(menuItem.getDescription());
}
else
{
break;
}

}
}
}//测试用例
static void Main(string[] args)
{
Menu pancakeHouseMenu = new PancakeHouseMenu();
Menu dinerMenu = new DinerMenu();
Waitress waitress = new Waitress(pancakeHouseMenu, dinerMenu);
waitress.printMenu();
Console.ReadLine();
}//测试结果



总结:

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

2.把游走的任务放在迭代器上,而不是聚合上。这样简化了聚合的接口和实现,也让责任各得其所。

扩展:

单一责任:一个类应该只有一个引起变化的原因。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: