Java设计模式之迭代器模式

来源:互联网 发布:装修网络推广 编辑:程序博客网 时间:2024/06/15 04:10

一、概念

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

关系图:



二、应用实例

1.遍历不同类型的菜单。

关系图:



代码实现:

/** * 迭代器接口,所有迭代器实现该接口 * Created by 韩信 on 2017-11-18. */public interface Iterator {    boolean hasNext();    Object next();}

DinerMenuIterator类

/** * Created by 韩信 on 2017-11-18. */public class DinerMenuIterator implements Iterator {    private MenuItem[] items;    int position = 0;    public DinerMenuIterator(MenuItem[] items){        this.items = items;    }    @Override    public boolean hasNext() {        if(position >= items.length || items[position]==null){            return false;        }        return true;    }    @Override    public Object next() {        MenuItem menuItem = items[position];        position ++;        return menuItem;    }}

PancakeHouseMenuIterator类

import java.util.List;/** * Created by 韩信 on 2017-11-18. */public class PancakeHosuseMenuIterator implements  Iterator {    private List<MenuItem> list;    int position = 0;    public PancakeHosuseMenuIterator(List<MenuItem> list){        this.list = list;    }    @Override    public boolean hasNext() {        position++;        return position>=list.size()? false:true;    }    @Override    public Object next() {        return list.get(position);    }}
Menu接口

/** * 菜单接口 * Created by 韩信 on 2017-11-18. */public interface Menu {    Iterator createIterator();}
MenuItem类

/** * 菜单描述 * Created by 韩信 on 2017-11-18. */public class MenuItem {    String name;    String desceiption;    boolean vegetarian;    double price;    public MenuItem(String name,String desceiption,boolean vegetarian,double price){        this.name = name;        this.desceiption = desceiption;        this.vegetarian = vegetarian;        this.price = price;    }}
DinerMenu类

/** * Created by 韩信 on 2017-11-18. */public class DinerMenu implements Menu{    static final  int MAX_TIEMS = 6;    int numberOfItem = 0;    MenuItem[] menuItems;    public Iterator createIterator(){        return new DinerMenuIterator(this.menuItems);    }    public DinerMenu(){        menuItems = new MenuItem[MAX_TIEMS];        addItem("Vegetarian BLT","descript1",true,2.99);        addItem("BLT","descript2",false,2.99);        addItem("Soup of the day","descript3",false,3.29);        addItem("Hotdog","descript4",false,3.05);    }    public void addItem(String name,String desceiption,boolean vegetarian,double price){        MenuItem menuItem = new MenuItem(name,desceiption,vegetarian,price);        if(numberOfItem >= MAX_TIEMS){            System.out.println("menu is full!");        }else{            menuItems[numberOfItem] = menuItem;            numberOfItem ++;        }    }    public MenuItem[] getMenuItems() {        return menuItems;    }}
PancakeHouseMenu类

import java.util.ArrayList;import java.util.List;/** * Created by 韩信 on 2017-11-18. */public class PancakeHouseMenu implements Menu {    private List<MenuItem> menus;    public PancakeHouseMenu(){        menus = new ArrayList<>();        addItem("K&B's Pancake Breakfast","descript1",true,2.99);        addItem("Regular Pancake Breakfast","descript2",false,2.99);        addItem("Blueberry Pancakes","descript3",true,3.49);        addItem("waffles","descript4",true,3.59);    }    public void addItem(String name,String desceiption,boolean vegetarian,double price){        MenuItem menuItem = new MenuItem(name,desceiption,vegetarian,price);        menus.add(menuItem);    }    @Override    public Iterator createIterator() {        return new PancakeHosuseMenuIterator(menus);    }    public List<MenuItem> getMenus() {        return menus;    }}

测试:

/** * Created by 韩信 on 2017-11-18. */public class Test {    public static void main(String[] args) {        DinerMenu dinerMenu = new DinerMenu();        PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();        Iterator iterator = dinerMenu.createIterator();        Iterator iterator1 = pancakeHouseMenu.createIterator();        printMenu(iterator);        printMenu(iterator1);    }    private static void printMenu(Iterator iterator){        while (iterator.hasNext()){            MenuItem menuItem = (MenuItem) iterator.next();            System.out.println(menuItem.name);        }    }}

三、优缺点

1.优点:

  • 简化了遍历方式,对于对象集合的遍历,还是比较麻烦的,对于数组或者有序列表,我们尚可以通过游标来取得,但用户需要在对集合了解很清楚的前提下,自行遍历对象,但是对于hash表来说,用户遍历起来就比较麻烦了。而引入了迭代器方法后,用户用起来就简单的多了。
  • 可以提供多种遍历方式,比如说对有序列表,我们可以根据需要提供正序遍历,倒序遍历两种迭代器,用户用起来只需要得到我们实现好的迭代器,就可以方便的对集合进行遍历了。
  • 封装性良好,用户只需要得到迭代器就可以遍历,而对于遍历算法则不用去关心。
2.缺点:
  • 对于比较简单的遍历(像数组或者有序列表),使用迭代器方式遍历较为繁琐,大家可能都有感觉,像ArrayList,我们宁可愿意使用for循环和get方法来遍历集合。