zoukankan      html  css  js  c++  java
  • 老生常谈:迭代器模式

         有很多方法可以把对象堆起来成为一个集合。你可以把它们放进数组,堆栈,列表,或者是散列表中,这是你的自由。

         迭代器模式定义:提供一个方法顺序访问一个聚合对象中的各个元素,而又不暴露它内部的表示.迭代器模式把在元素之间的游走的责任交给迭代器,而不是聚合对象,这不仅让聚合的接口和实现变得更简洁,也可以让聚合更加专注在它所应该专注的事情上面,而不用去理会遍历的事情。

         迭代器类图:

       
       现在引用《Head First》原文来说明迭代器模式的用法。

       原本两家餐厅都是有自己的菜单实现方法,对象村餐厅的菜单用数组实现,而煎饼物的则应用List<>来实现,现在合并了,毕然在菜单上实现方法上要有统一性.两家餐厅都同意这种做法,但是他们又不想改变自己菜单的实现方法,因为在他们各自的餐厅中都有很多地方依赖于自己菜单的实现方法.那么还能不能进行统一呢?答案是肯定的.他们有一个共同的特点:就是都是针对聚合对象操作,无论是散列表,堆栈,List<>,等等,两家菜单都要有遍历自己菜单的功能。这里都引入了迭代器模式。

       
       
       统一的迭代器接口:
       
    public  interface Iterator<T>
        
    {
            
    //判断是否有下一个
            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;      
           }

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

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

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

           }

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

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

        }
          
         5:client调用:简单的打印出了两家餐厅的所有菜单项的名称。
       
    PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
                DinerMenu dinerMenu 
    = new DinerMenu();
                Waitress waitress 
    = new Waitress(pancakeHouseMenu, dinerMenu);
                
    string s = waitress.printMenu();
                
    this.Label1.Text = s;
       
         总结:迭代器模式针对多种聚合对象操作的实现特别有帮助,可以将多种不同的聚合对象统一起来。
  • 相关阅读:
    求求你规范下你的代码风格
    为啥用ip不可以访问知乎,而百度却可以?
    漫画:htts是如何保证一台主机把数据安全发给另一台主机
    如何从亿量级中判断一个数是否存在?
    广播路由算法 :我是如何优雅着把悄悄话带给其他人的
    什么?你不知道0.0.0.0和255.255.255.255这两个地址是干嘛的?
    一篇文章带你学会Linux三剑客之一:awk
    你真的了解 i++, ++i 和 i+++++i 以及 i+++i++ 吗?
    通俗易懂讲解TCP流量控制机制,了解一下
    一文读懂拥塞控制
  • 原文地址:https://www.cnblogs.com/ASPNET2008/p/1192418.html
Copyright © 2011-2022 走看看