介绍
迭代器模式(Iterator Pattern)提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。
主要解决:不同的方式来遍历整个整合对象。
何时使用:遍历一个聚合对象。
关键代码:定义接口:hasNext, next。
**应用实例:**JAVA 中的 iterator。
优点:
1、它支持以不同的方式遍历一个聚合对象。
2、迭代器简化了聚合类。
3、在同一个聚合上可以有多个遍历。
4、在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。
缺点:由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。
使用场景: 1、访问一个聚合对象的内容而无须暴露它的内部表示。 2、需要为聚合对象提供多种遍历方式。 3、为遍历不同的聚合结构提供一个统一的接口。
实例
有两个店,一个以集合为菜单的早餐店和一个以数组为菜单的午餐店,他们都是聚合类。每个菜单都有一个菜单项。有一个服务员根据提供的菜单展示给客户看。迭代器类将简化聚合类。
店的抽象类
public interface Menu {
public Iterator<MenuItem> createIterator();
}
菜单项
/**
* 菜单项
* 名称
* 叙述
* 是否为素食
* 价格
* @author lenovo
*
*/
public class MenuItem {
String name;
String description;
boolean vegetaraian;
double price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public boolean isVegetaraian() {
return vegetaraian;
}
public void setVegetaraian(boolean vegetaraian) {
this.vegetaraian = vegetaraian;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public MenuItem(String name, String description, boolean vegetaraian, double price) {
super();
this.name = name;
this.description = description;
this.vegetaraian = vegetaraian;
this.price = price;
}
@Override
public String toString() {
return "MenuItem [name=" + name + ", description=" + description + ", vegetaraian=" + vegetaraian + ", price="
+ price + "]";
}
}
午餐店和早餐店
public class DinerMenu implements Menu{
static final int MAX_ITEMS = 6;
int numberOfItems = 0;
MenuItem[] menuItems;
public DinerMenu() {
menuItems = new MenuItem[MAX_ITEMS];
addItem("牛肉盖浇饭", "精选牛肉", false, 10.99);
addItem("蟹棒芝士饭", "精选蟹棒", false, 10.99);
addItem("滑鸡荷叶饭", "精选滑鸡", false, 10.99);
addItem("鸡蛋瘦肉饭", "精选瘦肉", false, 10.99);
}
public void addItem(String name,String description,boolean vegetarian,double price){
MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
if(numberOfItems>=MAX_ITEMS){
System.err.println("对不起,我们只有6个菜");
}else{
menuItems[numberOfItems] = menuItem;
numberOfItems++;
}
}
@Override
public Iterator<MenuItem> createIterator(){
return new DinerMenuIterator(menuItems);
}
}
/**
* 煎饼屋菜单
* @author lenovo
*
*/
public class PancakeHouseMenu implements Menu{
ArrayList<MenuItem> menuItems;
public PancakeHouseMenu() {
menuItems = new ArrayList<MenuItem>();
addItem("早餐煎饼", "鸡蛋烤箱煎饼", true, 2.99);
addItem("早餐豆浆","原味豆浆",true,2.99);
addItem("早餐油条","早餐油条 ",true,2.99);
addItem("牛肉面条","手擀面",false,5.99);
}
public void addItem(String name,String description,boolean vegetarian,double price){
MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
menuItems.add(menuItem);
}
@Override
public Iterator<MenuItem> createIterator(){
return menuItems.iterator();
}
}
数组午餐店的迭代器
public class DinerMenuIterator implements Iterator<MenuItem>{
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;
}else{
return true;
}
}
@Override
public MenuItem next() {
MenuItem menuItem = items[position];
position++;
return menuItem;
}
}
关于集合早餐店的迭代器,该迭代器使用集合提供的迭代器即可,无需再写迭代器
服务员类
public class Waitress {
PancakeHouseMenu pancakeHouseMenu;
DinerMenu dineMenu;
public Waitress(PancakeHouseMenu pancakeHouseMenu,DinerMenu dineMenu) {
this.pancakeHouseMenu = pancakeHouseMenu;
this.dineMenu = dineMenu;
}
public void printMenu(){
Iterator<MenuItem> items = pancakeHouseMenu.createIterator();
Iterator<MenuItem> items1 =dineMenu.createIterator();
System.out.println("煎饼屋的菜单");
printIterator(items);
System.out.println("午餐店的菜单");
printIterator(items1);
}
private void printIterator(Iterator<MenuItem> items){
while(items.hasNext()){
System.out.println(items.next());
}
}
}
用户类
public class Client {
public static void main(String[] args) {
PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
DinerMenu dineMenu = new DinerMenu();
Waitress waitress = new Waitress(pancakeHouseMenu,dineMenu);
waitress.printMenu();
}
}