您的位置:首页 > 其它

《10》迭代器模式

2016-03-02 14:25 281 查看
迭代器模式:

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

理解:
类似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<>();
}

@Override
void 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];
}

@Override
void 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<>();
}

@Override
void addItem(Food food) {
menuItems.add(food);
}

@Override
Iterator createIterator() {
// TODO Auto-generated method stub
return 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];
}

@Override
void addItem(Food food) {
if(pos >= MAX_SIZE){
return;
}
menuitems[pos] = food;
pos++;
}

@Override
Iterator 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;
}

@Override
public boolean hasNext() {
if (pos >= menuItems.length || menuItems[pos] == null) {
return false;
}
return true;
}

@Override
public Object next() {
return menuItems[pos++];
}

@Override
public 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接口即可
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息