设计模式——迭代器模式

迭代器模式是什么?

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

迭代器模式解决什么问题?

现有MenuItem作为菜单项,BreakfastMenu采用ArrayList实现,LunchMenu采用数组实现:

class MenuItem {
    private String name;
    private Double price;

    public MenuItem(String name, Double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public Double getPrice() {
        return price;
    }
}

class BreakfastMenu {
    ArrayList<MenuItem> menuItems;

    public BreakfastMenu() {
        menuItems = new ArrayList<>();
        addItem("包子", 1.5);
        addItem("烧卖", 1.5);
    }

    public void addItem(String name, double price) {
        MenuItem item = new MenuItem(name, price);
        menuItems.add(item);
    }

    public ArrayList<MenuItem> getMenuItems() {
        return menuItems;
    }
}

class LunchMenu {
    static final int MAX_ITEM = 6;
    int number = 0;
    MenuItem[] menuItems;

    public LunchMenu() {
        menuItems = new MenuItem[MAX_ITEM];
        addItem("鱼香肉丝", 15);
        addItem("西红柿炒蛋", 15);
    }

    public void addItem(String name, double price) {
        MenuItem item = new MenuItem(name, price);
        if (number > MAX_ITEM) {
            System.out.println("菜单满了");
        } else {
            menuItems[number] = item;
            number += 1;
        }
    }

    public MenuItem[] getMenuItems() {
        return menuItems;
    }
}

如果要打印早午餐的菜单,只能通过getMenuItems()获取到ArrayList数据和数组数据分别进行打印

BreakfastMenu breakfastMenu = new BreakfastMenu();
ArrayList<MenuItem> breakfastMenuItems = breakfastMenu.getMenuItems();
for (int i = 0; i < breakfastMenuItems.size(); i++) {
    System.out.println(breakfastMenuItems.get(i).getName() + breakfastMenuItems.get(i).getPrice());
}

LunchMenu lunchMenu = new LunchMenu();
MenuItem[] lunchMenuItems = lunchMenu.getMenuItems();
for (int i = 0; i < lunchMenuItems.length; i++) {
    System.out.println(lunchMenuItems[i].getName() + lunchMenuItems[i].getPrice());
}

现如今两个菜单合并,以后可能有更多不同数据结构存储的菜单,如何将这些菜单统一遍历?

迭代器模式实现

迭代器接口

新建迭代器接口:

interface MyIterator {
    boolean hasNext();
    Object next();
}

迭代器实例

LunchMenuIterator处理数组的遍历,BreakfastMenuIterator处理ArrayList的遍历:

class LunchMenuIterator implements MyIterator {
    MenuItem[] menuItems;
    int position = 0;

    public LunchMenuIterator(MenuItem[] menuItems) {
        this.menuItems = menuItems;
    }

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

    @Override
    public Object next() {
        MenuItem menuItem = menuItems[position];
        position += 1;
        return menuItem;
    }
}

class BreakfastMenuIterator implements MyIterator {
    ArrayList<MenuItem> menuItems;
    int position = 0;

    public BreakfastMenuIterator(ArrayList<MenuItem> menuItems) {
        this.menuItems = menuItems;
    }

    @Override
    public boolean hasNext() {
        if (position >= menuItems.size() || menuItems.get(position) == null) {
            return false;
        } else {
            return true;
        }
    }

    @Override
    public Object next() {
        MenuItem menuItem = menuItems.get(position);
        position += 1;
        return menuItem;
    }
}

用于创建迭代器的接口

新建Menu接口用于创建迭代器:

interface Menu {
    MyIterator createIterator();
}

用于创建迭代器的实例

将LunchMenu和BreakfastMenu的getMenuItems()方法改为返回其对应迭代器:

class LunchMenu implements Menu {
    static final int MAX_ITEM = 6;
    int number = 0;
    MenuItem[] menuItems;

    public LunchMenu() {
        menuItems = new MenuItem[MAX_ITEM];
        addItem("鱼香肉丝", 15);
        addItem("西红柿炒蛋", 15);
    }

    public void addItem(String name, double price) {
        MenuItem item = new MenuItem(name, price);
        if (number > MAX_ITEM) {
            System.out.println("菜单满了");
        } else {
            menuItems[number] = item;
            number += 1;
        }
    }

    public MyIterator createIterator() {
        return new LunchMenuIterator(menuItems);
    }
}
class BreakfastMenu implements Menu {
    ArrayList<MenuItem> menuItems;

    public BreakfastMenu() {
        menuItems = new ArrayList<>();
        addItem("包子", 1.5);
        addItem("烧卖", 1.5);
    }

    public void addItem(String name, double price) {
        MenuItem item = new MenuItem(name, price);
        menuItems.add(item);
    }

    public MyIterator createIterator() {
        return new BreakfastMenuIterator(menuItems);
    }
}

迭代过程

通过获取MyIterator,调用其中的hasNext()和next()即可对ArrayList和数组无差别遍历,还可对while循环进一步封装:

Menu breakfastMenu = new BreakfastMenu();
MyIterator breakfastIterator = breakfastMenu.createIterator();
while (breakfastIterator.hasNext()) {
     MenuItem menuItem = (MenuItem) breakfastIterator.next();
     System.out.println(menuItem.getName() + " " + menuItem.getPrice());
}

Menu lunchMenu = new LunchMenu();
MyIterator lunchIterator = lunchMenu.createIterator();
while (lunchIterator.hasNext()) {
    MenuItem menuItem = (MenuItem) lunchIterator.next();
    System.out.println(menuItem.getName() + " " + menuItem.getPrice());
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值