ASP.NET2.0

网站开发

《Head First》中的迭代器模式

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

     迭代器模式定义:

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

     迭代器类图:

   
   现在引用《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);

       }

    }
     
     这是菜单项具体内容:
     为了简化代码,在这就写了菜单项的名称,其它的省略了。
    
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; }
       
       }

    }
      
    页面服务员调用代码:有了菜单还得要有服务的服务,服务员的责任就是打印出来两家餐厅的所在菜单项供客人点餐.
    
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;
       
       }

    }
      
     client调用
      本人常用BS架构,为此这就用一个网页的形式调用实现了。简单的打印出了两家餐厅的所有菜单项的名称。
   
PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
            DinerMenu dinerMenu 
= new DinerMenu();
            Waitress waitress 
= new Waitress(pancakeHouseMenu, dinerMenu);
            
string s = waitress.printMenu();
            
this.Label1.Text = s;
   
     总结:迭代器模式针对多种聚合对象操作的实现特别有帮助,可以将多种不同的聚合对象统一起来。
Tag标签: C#,.NET

posted on 2008-05-11 17:31 姜敏 阅读(848) 评论(4)  编辑 收藏 所属分类: 设计模式

Feedback

#1楼  2008-05-12 08:42 王孟军!      

对模式研究得挺深的,以后多交流
wmj.cnblogs.com   回复  引用  查看    

#2楼 [楼主] 2008-05-12 08:45 姜敏      

@ 王孟军
您也是湖南的吗?上次看了下好像是,哈哈,我是您团队的成员,以后多多交流.   回复  引用  查看    

#3楼  2008-05-12 10:58 王孟军!      

我是湖南的,
你呢?
  回复  引用  查看    

#4楼 [楼主] 2008-05-12 16:01 姜敏      

@王孟军!
我也是湖南的,希望以后多多交流,哈哈.   回复  引用  查看    


标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-05-11 17:40 编辑过
 
另存  打印