迭代器模式(Iterator Pattern)

    xiaoxiao2021-03-28  30

     迭代器模式:让客户遍历你的对象而又无法窥视你存储对象的方式

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

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

    //类似工厂模式,子类需要实现创建枚举对象的方法 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.把游走的任务放在迭代器上,而不是聚合上。这样简化了聚合的接口和实现,也让责任各得其所。

    扩展:

    单一责任:一个类应该只有一个引起变化的原因。

    转载请注明原文地址: https://ju.6miu.com/read-664709.html

    最新回复(0)