您的位置:首页 > 编程语言 > C#

设计模式C#实现(四)——迭代器模式

2015-08-25 14:46 501 查看
迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。

  UML类图:

  


  煎饼屋和餐厅合并了!但是有个小问题,虽然两家都同意实现相同的菜单项MenuItem,但是煎饼屋想使用ArrayList储存菜单项,而餐厅则使用数组,为了使女招待能同时访问两家的菜单,我们需要为菜单提供一个统一的访问接口。

  先来看菜单项MenuItem,两家店的实现相同

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;
}

}


  接口Menu,它只定义了一个创建迭代器的方法,实现这个接口的类将提供各自不同的迭代器

interface Menu
{
Iterator createIterator();
}


  煎饼屋菜单,实现了Menu接口

class PancakeHouseMenu : Menu
{
ArrayList menuItems;
public PancakeHouseMenu()
{
menuItems = new ArrayList();
addItem("K&B's Pancake Breakfast", "Pancakes with scrambled eggs,and toast", true, 2.99);
addItem("Regular Pancake Breakfast", "Pancakes with fired eggs,and sausage", false, 2.99);
addItem("Blueberry Pancake", "Pancakes with fresh blueberries", true, 3.49);
addItem("Waffles", "Waffles,with your choice of blueberries or strawberries", 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 Iterator createIterator()
{
return new PancakeHouseIterator(menuItems);
}
//菜单的其他方法
}


  餐厅菜单同样如此

class DinerMenu : Menu
{
static int Max_ITEMS = 6;
int numberOfItems = 0;
MenuItem[] menuItems;
public DinerMenu()
{
menuItems = new MenuItem[Max_ITEMS];
addItem("Vegetarian BLT", "(Fakin') Bacon with lettuce & tomato on whole wheat", true, 2.99);
addItem("BLT", "Bacon with lettuce & tomato on whole wheat", false, 2.99);
addItem("Soup of the day", "Soup of the day,whit a side of potato salad", false, 3.29);
addItem("Hot dog", "A hot dog, with saurkraut, relish, onions, topped with cheese", false, 3.05);

}
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("Sorry,menu is full! Can't add item to menu!");
}
else
{
menuItems[numberOfItems] = menuItem;
numberOfItems++;
}
}
public MenuItem[] getMenuItems()
{
return menuItems;
}
public Iterator createIterator()
{
return new DinerMenuIterator(menuItems);
}
//菜单的其他方法
}  


  接下来看看迭代器,迭代器有一个接口,定义了一些操作

interface Iterator
{
bool hasNext();
object next();
//更多的方法,例如remove...
}


  不同的菜单有不同的迭代器,这是煎饼屋的

class PancakeHouseIterator:Iterator
{
ArrayList items;
int position = 0;
public PancakeHouseIterator(ArrayList items)
{
this.items = items;
}
public object next()
{
MenuItem menuItem = (MenuItem)items[position];
position++;
return menuItem;
}
public bool hasNext()
{
if (position>=items.Count)
{
return false;
}
else
{
return true;
}
}
}


  这是餐厅的

class DinerMenuIterator:Iterator
{
MenuItem[] items;
int position = 0;
public DinerMenuIterator(MenuItem[] items)
{
this.items = items;
}
public object next()
{
MenuItem menuItem = items[position];
position++;
return menuItem;
}
public bool hasNext()
{
if (position>=items.Length||items[position]==null)
{
return false;
}
else
{
return true;
}
}
}


  选择女招待可以方便的用统一的方法操作两家的菜单了

class Waitress
{
Menu pancakeHouseMenu;
Menu dinerMenu;
public Waitress(Menu pancake, Menu diner)
{
this.pancakeHouseMenu = pancake;
this.dinerMenu = diner;
}
public void printMenu()
{
Iterator pancakeIterator = pancakeHouseMenu.createIterator();
Iterator dinerIterator = dinerMenu.createIterator();
Console.WriteLine("MENU\n----\nBREAKFAT");
printMenu(pancakeIterator);
Console.WriteLine("\nLUNCH");
printMenu(dinerIterator);
}
private void printMenu(Iterator iterator)
{
while (iterator.hasNext())
{
MenuItem menuItem = (MenuItem)iterator.next();
Console.Write(menuItem.getName() + ",");
Console.WriteLine(menuItem.getPrice() + "--  ");
Console.WriteLine("     "+menuItem.getDescription());
}
}
}


  迭代器的好处是将来如果有新的菜单加入,而它使用了不同的存储方法(例如hashtable),只需要让它实现迭代器接口,而不必修改女招待的操作方式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: