《10》迭代器模式

来源:互联网 发布:网络防雷器 编辑:程序博客网 时间:2024/06/07 16:10

迭代器模式:



定义:

定义一种统一的方法顺序访问聚合对象中的各个元素,而不爆露其内部的表示


理解:

类似java中的迭代器的职能,只不过java中的迭代器之适用标准的集合类,而这里是自定义一种迭代器的功能,适用聚合对象



例子:

一个餐厅的服务员,向客人打印菜单(午餐、晚餐),而午餐和晚餐共同实现统一的接口,实现如下



public abstract class Menu {abstract void addItem(Food food);}

public class LunchMenu extends Menu{private ArrayList<Food> menuItems;public LunchMenu() {menuItems = new ArrayList<>();}@Overridevoid addItem(Food food) {menuItems.add(food);}}

public class DinnerMenu extends Menu{private final int MAX_SIZE  = 5; private Food[] menuitems;private int pos = 0;public DinnerMenu() {menuitems = new Food[MAX_SIZE];}@Overridevoid addItem(Food food) {if(pos >= MAX_SIZE){return;}menuitems[pos] = food;pos++;}}



可以看到一个使用了ArrayList;另一个使用的是一个Food[]数组

问题来了:怎么让Waiter打印菜单,而不会关心菜单是一个什么数据结构?






分析:

不关心,意思是任意一个类型的菜单都可以喽,那么可以将不同种类的菜单抽象一个统一的接口,让waiter的感觉像是在访问标准的数据类型,而不是感觉像数组这种奇怪的东西



开始我们的代码设计


1.修改Menu接口

public abstract class Menu {abstract void addItem(Food food);abstract Iterator createIterator();}


2.重新修改子类(为waiter提供统一的iterator遍历方法)

public class LunchMenu extends Menu{private ArrayList<Food> menuItems;public LunchMenu() {menuItems = new ArrayList<>();}@Overridevoid addItem(Food food) {menuItems.add(food);}@OverrideIterator createIterator() {// TODO Auto-generated method stubreturn menuItems.iterator();}}


public class DinnerMenu extends Menu{private final int MAX_SIZE  = 5; private Food[] menuitems;private int pos = 0;public DinnerMenu() {menuitems = new Food[MAX_SIZE];}@Overridevoid addItem(Food food) {if(pos >= MAX_SIZE){return;}menuitems[pos] = food;pos++;}@OverrideIterator createIterator() {return new DinnerMenuIterator(menuitems);}}



3.ArrayList已有标准的Iterator接口,现为Food[]数组配置伪Iterator

public class DinnerMenuIterator implements Iterator {private Food[] menuItems;private int pos = 0;public DinnerMenuIterator(Food[] menuItems) {this.menuItems = menuItems;}@Overridepublic boolean hasNext() {if (pos >= menuItems.length || menuItems[pos] == null) {return false;}return true;}@Overridepublic Object next() {return menuItems[pos++];}@Overridepublic void remove() {return;}}



4.下面看看Waiter的使用:

public class Waiter {public static void main(String[] args) {LunchMenu lunch = new LunchMenu();lunch.addItem(new Food(1, "土豆", 10));lunch.addItem(new Food(2, "米饭", 5));lunch.addItem(new Food(3, "鸡肉", 12));lunch.addItem(new Food(4, "鱼肉", 11));// ----------------------DinnerMenu dinner = new DinnerMenu();dinner.addItem(new Food(1, "白米粥", 5));dinner.addItem(new Food(2, "豆浆", 5));dinner.addItem(new Food(3, "煎饼果子", 5));dinner.addItem(new Food(4, "水果沙拉", 5));dinner.addItem(new Food(5, "碳酸饮料", 5));//-----------------------print(lunch.createIterator());print(dinner.createIterator());}private static void print(Iterator createIterator) {Iterator iterator = createIterator;while(iterator.hasNext()){System.out.println(iterator.next().toString());}System.out.println("//------------------------");}}



5.结果

1:土豆:10

2:米饭:5

3:鸡肉:12

4:鱼肉:11

//------------------------

1:白米粥:5

2:豆浆:5

3:煎饼果子:5

4:水果沙拉:5

5:碳酸饮料:5

//------------------------



优点:

1.可以隐藏聚合对象中内部表示

2.提供统一的接口,将Waiter和菜单解耦,可以任意替换菜单只需提供iterator接口即可






























0 0
原创粉丝点击