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

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

  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
----
BREAKFAT");
            printMenu(pancakeIterator);
            Console.WriteLine("
LUNCH");
            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),只需要让它实现迭代器接口,而不必修改女招待的操作方式。

原文地址:https://www.cnblogs.com/castdream/p/4747030.html