迭代器模式(Iterator Pattern)

来源:互联网 发布:淘宝网开设网店的规律 编辑:程序博客网 时间:2024/05/17 22:33

迭代器模式定义:Iterator Pattern提供一种方法顺序访问一个聚合元素中的各个元素,而又不暴漏内部方法

酒吧提供beer和wine:


public class Bar {private List<String> barMenu;public Bar(){barMenu = new ArrayList<String>();barMenu.add("beer");barMenu.add("wine");}public List<String> getMenu(){return barMenu;}}

餐厅提供rice、soup和noodles:


public class Restaurant {private String[] restaurantMenu;public Restaurant(){restaurantMenu = new String[3];restaurantMenu[0] = "rice";restaurantMenu[1] = "soup";restaurantMenu[2] = "noodles";}public String[] getMenu(){return restaurantMenu;}}

现在要将酒吧与餐厅整合为一个点餐系统,在该点餐系统中既能看到酒吧的所有饮品,又能看到餐厅的所有餐点,通常的处理方式为:


public class OrderSystem {private Bar bar;private Restaurant reataurant;public OrderSystem(Bar bar,Restaurant reataurant){this.bar = bar;this.reataurant = reataurant;}public void printMenu(){List<String> bMenus = bar.getMenu();String[] rMenus = reataurant.getMenu();if(null != bMenus && bMenus.size() > 0){for(String name : bMenus){System.out.println(name);}}if(null != rMenus){for(int i = 0;i < rMenus.length; i++){if(null != rMenus[i]){System.out.println(rMenus[i]);}}}}

1,OrderSystem类与具体集合类型(String[]以及List<String>)、具体实现(for循环)耦合

2,OrderSystem类与具体餐厅类耦合,即使这两个餐厅类提供的方法相同

先来考虑问题1,显然我们需要进行封装以隐藏具体集合类型与实现过程

从OrderSystem类中可以看出,其对集合的操作为遍历,那么封装类需要提供方法以使我们可以遍历其封装的不同集合


public interface Iterator {public boolean hasNext();public Object next() throws Exception;}
public class BarIterator implements Iterator {private List<String> menu;int nextPosition = 0;public BarIterator(List<String> menu){this.menu = menu;}public boolean hasNext() {if(menu.size() > nextPosition && null != menu.get(nextPosition)){return true;}return false;}public Object next() throws Exception {if(menu.size() > nextPosition && null != menu.get(nextPosition)){Object result = menu.get(nextPosition);nextPosition++;return result;}throw new Exception("越界");}}
public class RestaurantIterator implements Iterator {private String[] menu;int nextPosition = 0;public RestaurantIterator(String[] menu){this.menu = menu;}public boolean hasNext() {if(menu.length > nextPosition && null != menu[nextPosition]){return true;}return false;}public Object next() throws Exception {if(menu.length > nextPosition && null != menu[nextPosition]){Object result = menu[nextPosition];nextPosition++;return result;}throw new Exception("越界");}}
public class Bar {private List<String> barMenu;public Bar(){barMenu = new ArrayList<String>();barMenu.add("beer");barMenu.add("wine");}public Iterator getMenu(){return new BarIterator(barMenu);}}
public class Restaurant {private String[] restaurantMenu;public Restaurant(){restaurantMenu = new String[3];restaurantMenu[0] = "rice";restaurantMenu[1] = "soup";restaurantMenu[2] = "noodles";}public RestaurantIterator getMenu(){return new RestaurantIterator(restaurantMenu);}}
public class OrderSystem {private Bar b;private Restaurant r;public OrderSystem(Bar b,Restaurant r){this.b = b;this.r = r;}public void printMenu(){Iterator bit = b.getMenu();Iterator rit = r.getMenu();printMenu(bit);printMenu(rit);}private void printMenu(Iterator it){try{while(it.hasNext()){Object tmp = it.next();if(null != tmp){System.out.println(tmp.toString());}}}catch(Exception e){System.out.println(e.getMessage());}}public static void main(String[] args){Bar b = new Bar();Restaurant r = new Restaurant();OrderSystem h = new OrderSystem(b,r);h.printMenu();}}

封装的遍历方法没有加锁,在多线程环境下是不适用的

看看设计中的Iterator类是不是和java.util.Iterator十分相似?

/* * @(#)Iterator.java1.27 06/07/24 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package java.util;/** * An iterator over a collection.  Iterator takes the place of Enumeration in * the Java collections framework.  Iterators differ from enumerations in two * ways: <ul> *<li> Iterators allow the caller to remove elements from the *     underlying collection during the iteration with well-defined *      semantics. *<li> Method names have been improved. * </ul><p> * * This interface is a member of the  * <a href="{@docRoot}/../technotes/guides/collections/index.html"> * Java Collections Framework</a>. * * @author  Josh Bloch * @version 1.27, 07/24/06 * @see Collection * @see ListIterator * @see Enumeration * @since 1.2 */public interface Iterator<E> {    /**     * Returns <tt>true</tt> if the iteration has more elements. (In other     * words, returns <tt>true</tt> if <tt>next</tt> would return an element     * rather than throwing an exception.)     *     * @return <tt>true</tt> if the iterator has more elements.     */    boolean hasNext();    /**     * Returns the next element in the iteration.     *     * @return the next element in the iteration.     * @exception NoSuchElementException iteration has no more elements.     */    E next();    /**     *      * Removes from the underlying collection the last element returned by the     * iterator (optional operation).  This method can be called only once per     * call to <tt>next</tt>.  The behavior of an iterator is unspecified if     * the underlying collection is modified while the iteration is in     * progress in any way other than by calling this method.     *     * @exception UnsupportedOperationException if the <tt>remove</tt>     *  operation is not supported by this Iterator.          * @exception IllegalStateException if the <tt>next</tt> method has not     *  yet been called, or the <tt>remove</tt> method has already     *  been called after the last call to the <tt>next</tt>     *  method.     */    void remove();}
再来考虑问题2:与具体餐厅类耦合很容易处理-面向接口编程

这里使用java.util.Iterator


不想实现的方法就抛出默认异常,上面的Iterator类源代码中说的很清楚了:

public class RestaurantIterator implements Iterator<String> {private String[] menu;int nextPosition = 0;public RestaurantIterator(String[] menu){this.menu = menu;}public boolean hasNext() {if(menu.length > nextPosition && null != menu[nextPosition]){return true;}return false;}public String next(){if(menu.length > nextPosition && null != menu[nextPosition]){String result = menu[nextPosition];nextPosition++;return result;}throw new NoSuchElementException();}public void remove(){throw new UnsupportedOperationException();}}
public interface R {public Iterator<String> getMenu();}
public class Bar implements R{private List<String> barMenu;public Bar(){barMenu = new ArrayList<String>();barMenu.add("beer");barMenu.add("wine");}public Iterator<String> getMenu(){return barMenu.iterator();}}
public class Restaurant implements R{private String[] restaurantMenu;public Restaurant(){restaurantMenu = new String[3];restaurantMenu[0] = "rice";restaurantMenu[1] = "soup";restaurantMenu[2] = "noodles";}public Iterator<String> getMenu(){return new RestaurantIterator(restaurantMenu);}}
public class OrderSystem {private Bar b;private Restaurant r;public OrderSystem(Bar b,Restaurant r){this.b = b;this.r = r;}public void printMenu(){Iterator<String> bit = b.getMenu();Iterator<String> rit = r.getMenu();printMenu(bit);printMenu(rit);}private void printMenu(Iterator<String> it){try{while(it.hasNext()){Object tmp = it.next();if(null != tmp){System.out.println(tmp.toString());}}}catch(Exception e){System.out.println(e.getMessage());}}public static void main(String[] args){Bar b = new Bar();Restaurant r = new Restaurant();OrderSystem h = new OrderSystem(b,r);h.printMenu();}}
List可以自动返回一个封装好的Iterator
    /**     * Returns an iterator over the elements in this list in proper sequence.     *     * @return an iterator over the elements in this list in proper sequence     */    Iterator<E> iterator();

原创粉丝点击