您当前位置:设计在线网 >> JavaScript >> 浏览文章

Java代码设计之迭代器模式

分享到:
本文章讲述了Java代码设计之迭代器模式.

Java设

计模式之迭代器模式和组合模式详细讲解:

一、 迭代器模式

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

  迭代器模式,允许访问聚合中的各个元素,为客户提供了统一的方法去访问各个集合,屏蔽了具体集合的类型,无论是List,Map,Set,散列表,数组等集合,在客户端表现的都是一种方法来获取该集合中的元素。

  通常迭代器将遍历聚合的工作封装进一个对象中,在我们使用迭代器的时候,我们依赖聚合提供遍历,通常聚合都会返回一个迭代器。这样就可以让集合只专注于元素的操作,而将对于元素游走的遍历工作放在迭代器上执行,这样就可以简化聚合的接口和实现。如果你有一个统一的方法来访问聚合中的每一个对象,则就可以利用多态的代码和这些聚合搭配。

  迭代器类图如下:

点击浏览下一页

  Aggregate:主要是一种接口,提供了一个方法来给客户端,客户端可以利用该方法来返回一个对于聚合元素访问遍历的迭代器,而不用关心聚合是数组,列表等集合类型

  ConcreteAggregate:是实现了该接口,这个是具体聚合持有了一个对象的集合,每一个具体聚合都要负责实例化与之丢应的具体迭代器,此迭代器能够遍历对象集合。

  Iterator:这是所有迭代器都要实现的接口,一般可以直接实现Java系统自带的Iterator。

  ConcreteIterator:对于特定聚合对象进行遍历的算法。它主要负责遍历对象,以及判断对象。

  注:在常用的各种集合对象中,list,Set均可以直接调用它们的方法List.iterator();和Set.iterator();

  一般对于如果是数组类型的,则就需要专门为数组做一个迭代器来转换它的遍历方式

  对于Map集合的,由于Map集合是键值对的,所以要想取得它的值,

  Map.values.iterator();//首先返回值的对象所有集合,然后再生成迭代器

  一般迭代器是向前移动的,但是也可以实现向后移动,有一个ListIterator,这个可以实现向后移动元素的访问。迭代器遍历的结果并不是表示元素的大小次序的。在利用迭代器中,当一个方法的参数是一个迭代器的时候,其实就是使用了多态,我们此时针对接口编程而不是具体类编程,从而可以在不同的集合中遍历。

  当然如果不想创建迭代器,可以直接利用foreach

  代码示例:

  有三个聚合类,一个用ArrayList存储对象,一个用数组存储对象,一个利用HashMap。由于三个集合访问遍历集合中的元素不同,但是为了给客户端提供一个统一的访问方法,此时就可以利用迭代器模式,为每一个集合创建一个对象的迭代器,再在聚合类中实例化该迭代器返回给客户端,这样客户端就只管遍历,而不用关心具体的集合类型了。

  集合接口:主要是提供一个统一的方法来返回迭代器

package com.whut.iterator;
import java.util.Iterator;

public interface Menu {
  public Iterator createIterator();
}

  利用数组存储对象的具体集合

package com.whut.iterator;

import java.util.Iterator;

public class DinerMenu implements Menu{

  private static final int MAX_ITEMS=6;
  private int numberOfItems=0;
  private MenuItem[] menuItems;
  
  public DinerMenu()
  {
    menuItems=new MenuItem[MAX_ITEMS];
    addItem("Dinner Vegetarian","Bacon",true,2.99);
    addItem("Dinner BLT ","Bacon BLT",false,2.99);
    addItem("Dinner hotdog","A hot dog",false,3.48);
  }
  
  public void addItem(String name,String description,boolean vegetarian,double price)
  {
    MenuItem item=new MenuItem(name,description,vegetarian,price);
    if(numberOfItems<MAX_ITEMS)
    {
      menuItems[numberOfItems]=item;
      numberOfItems++;
    }
    else
      System.out.println("Sorry ,menu is full");
  }
  
  public Iterator createIterator()
  {
    return new DinerMenuIterator(menuItems);
  }
    
    
}

  利用ArrayList存储对象的具体集合

package com.whut.iterator;

import java.util.ArrayList;
import java.util.Iterator;
public class PancakeHouseMenu    implements Menu{

  private ArrayList menuItems;
  
  public PancakeHouseMenu()
  {
    menuItems=new ArrayList();
    addItem("K&B panckage breakfast","pancakes with scramed eggs and toast",true,2.99);
    addItem("Regular panckage breakfast","pancakes with fried eggs ",false,2.99);
    addItem("Blueberry breakfast","pancakes made with fresh blueberry ",true,3.48);
    addItem("Waffles","waffles, with your choice",true,3.59);
  }
  
  public void addItem(String name,String description,boolean vegetarian,double price)
  {
    MenuItem item=new MenuItem(name,description,vegetarian,price);
    menuItems.add(item);
  }
  public Iterator createIterator()
  {
    return menuItems.iterator();
  }
}

  利用HashMap存储对象的具体集合

package com.whut.iterator;

import java.util.HashMap;
import java.util.Iterator;

public class CoffeeMenu implements Menu{
  private HashMap menuItems=new HashMap(); 
  public CoffeeMenu()
  {
    addItem("Coffee Burger" ,"veggie burger on",true,3.99);
    addItem("Coffee Soup","A cup of the soup",false,3.69);
    addItem("Coffee Burrito","A large burrito",true,4.29);
  }

  public void addItem(String name,String description,boolean vegetarian,double price)
  {
    MenuItem item=new MenuItem(name,description,vegetarian,price);
    menuItems.put(item.getName(),item);
  }

  @Override
  public Iterator createIterator() {
    // TODO Auto-generated method stub
    //直接返回一个迭代器
    return menuItems.values().iterator();
  }
}

  由于为了统一数组和ArrayList和HashMap的遍历方法,需要为数组建立一个遍历算法

package com.whut.iterator;

import java.util.Iterator;

public class DinerMenuIterator implements Iterator {

  private MenuItem[] items;
  private int position=0;
  
  public DinerMenuIterator(MenuItem[] items)
  {
    this.items=items;
  }
  
  public boolean hasNext() {
         if(position>=items.length || items[position]==null)
    return false;
         else
             return true;
  }

  public Object next() {
    MenuItem menuItem=items[position];
    position=position+1;
    return menuItem;
  }

  public void remove() {

             if(position<=0)
                throw new IllegalStateException("You can't remove an item at least");
             if(items[position]!=null)
             {
                for(int i=position-1;i<items.length-1;i++)
                 items[i]=items[i+1];
                items[items.length-1]=null;
             }
  }

}

  提供一个来测试

package com.whut.iterator;

import java.util.Iterator;

public class Waitress {

  private Menu diner;
  private Menu house;
  private Menu cafe;
  public Waitress(Menu diner,Menu house,Menu cafe)
  {
    this.diner=diner;
    this.house=house;
    this.cafe=cafe;
  }
  
  public void printMenu()
  {
    Iterator houseIterator=house.createIterator();
    Iterator dinerIterator=diner.createIterator();
    Iterator cafeIterator=cafe.createIterator();
    System.out.println("-------houseMenu--------");
    printMenuItem(houseIterator);
    System.out.println();
    
    System.out.println("-------dinnerMenu--------");
    printMenuItem(dinerIterator);
    System.out.println();
    
    System.out.println("-------coffeeMenu--------");
    printMenuItem(cafeIterator);
  }
  
  private void printMenuItem(Iterator iterator)
  {
    while(iterator.hasNext())
    {
      MenuItem menuItem=(MenuItem)iterator.next();
      System.out.print(menuItem.getName()+"_||_"+menuItem.getPrice()
          +"_||_"+menuItem.getDescription());
      System.out.println();
    }
  }
}

  设计原则:

  一个类应该只有一个引起变化的原因。

推荐阅读:
基于Spring+Hibernate+Eclipse进行敏捷Java开发程序
Java中文乱码 文件编码与系统环境
基于Java中Serializable 序列化的作用

相关文章:

推荐文章  
赞助商链接  
热门排行  
主题推广  
中国设计在线网 All Rights Reserved. 互联网违法和不良信息举报
信息产业部备案号:湘ICP备09001063号