迭代器模式——demo

我们接着上次迭代器模式的例子,来优化一下,这次我们使用java自带的迭代器

因为 PancakeHouseMenu这个类里面的集合是ArrayList类型,则可以直接使用java默认的迭代器,不需要写它的迭代器

DinerMenu里面的集合类型是数组,而java默认的迭代器不支持数组的迭代,则需要自定义迭代器

我们再来重新整理一下各个类

首先是菜单项类,它没有任何变化

package iterator.demo;
 
/**
 * 菜单项
 */
public class MenuItem
{
	private String name;              //菜单项名称
	private String description;       //描述
	private double price;             //价格
 
	public MenuItem(String name,
                    String description,
                    double price)
	{
		this.name = name;
		this.description = description;
		this.price = price;
	}
 
	public String toString()
	{
		return (name + ": "+description+", $" + price);
	}
}

 接着是菜单类

package iterator.demo;
import java.util.Iterator;
 
public interface Menu
{
     /**
      * 添加菜单项
      * @param name
      * @param description
      * @param price
      */
     void addItem(String name, String description, double price);
 
     /**
      * 获取菜单项集合
      */
     Object getMenuItems();
 
     /**
      * 获取迭代器
      * @return
      */
      Iterator<MenuItem> createIterator();
}

然后是两个餐厅,他们都实现了Menu接口,煎饼屋餐厅使用的集合类支持迭代器,而对乡村餐厅使用的数组,不支持java自带的迭代器,需要自定义一个迭代器来遍历数组

package iterator.demo;
import java.util.ArrayList;
import java.util.Iterator;
 
/**
 * 煎饼屋餐厅
 */
public class PancakeHouseMenu implements Menu
{
	private ArrayList<MenuItem> menuItems;
 
	public PancakeHouseMenu()
	{
		menuItems = new ArrayList();
    
		addItem("薄煎饼早餐",
			"薄煎饼、鸡蛋和土司",
			2.99);
 
		addItem("蓝莓薄煎饼",
			"新鲜蓝莓和蓝莓果酱做成的薄煎饼",
			2.99);
 
		addItem("松饼",
			"松饼,可以选择蓝莓或者草莓口味",
			3.59);
	}
 
	public void addItem(String name, String description, double price)
	{
		MenuItem menuItem = new MenuItem(name, description, price);
		menuItems.add(menuItem);
	}
 
 
	public ArrayList<MenuItem> getMenuItems()
	{
		return menuItems;
	}
 
	public Iterator createIterator() {
		return  menuItems.iterator();
	}
}
package iterator.demo;


import java.util.Iterator;

/**
 * 对象村餐厅
 */
public class DinerMenu implements Menu
{
    private static final int MAX_ITEMS = 4;
    private int numberOfItems = 0;
    private MenuItem[] menuItems;
  
	public DinerMenu() {
		menuItems = new MenuItem[MAX_ITEMS];
 
		addItem("素食 BLT", "(煎)培根, 生菜和西红柿",  2.99);
		addItem("清汤", "一碗清汤, 配土豆沙拉", 3.29);
		addItem("热狗", "一个热狗, 酸菜, 芝士, 洋葱",  3.05);
		addItem("清蒸时蔬加糙米", "清蒸的蔬菜配糙米", 3.99);
	}
  
	public void addItem(String name, String description, double price)
	{
		MenuItem menuItem = new MenuItem(name, description,  price);
		if (numberOfItems >= MAX_ITEMS)
		{
			System.err.println("抱歉, 菜单已满! 不能添加菜单项");
		}
		else
		{
			menuItems[numberOfItems] = menuItem;
			numberOfItems = numberOfItems + 1;
		}
	}
 
	public MenuItem[] getMenuItems()
	{
		return menuItems;
	}

	public Iterator createIterator() {
		return  new DinerMenuIterator(menuItems);
	}
}

 由于对乡村餐厅DinerMenu里面是数组类型的集合,则需要自定义一个迭代器并实现Iterator接口

package iterator;

import item.MenuItem;

import java.util.Iterator;

public class DinerMenuIterator implements Iterator
{
    private MenuItem[] menuItems;
    private int position = 0;

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

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

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

接着来看看女服务员,我们把具体的类型改成了接口类型,这样 “通过针对接口编程,而不是针对实现编程“,我们就可以减少女接待员和具体类之间的依赖

package iterator.demo;

import java.util.Iterator;

public class Waitress
{
	private Menu pancakeHouseMenu;
	private Menu dinerMenu;

	public Waitress(Menu pancakeHouseMenu, Menu dinerMenu)
	{
		this.pancakeHouseMenu = pancakeHouseMenu;
		this.dinerMenu = dinerMenu;
	}


	public void printMenu() {
		Iterator pancakeIterator = pancakeHouseMenu.createIterator();
		Iterator dinerIterator = dinerMenu.createIterator();
		printMenu(pancakeIterator);
		printMenu(dinerIterator);

	}

	private void printMenu(Iterator<MenuItem> iterator) {
		while (iterator.hasNext()) {
			MenuItem menuItem = iterator.next();
			System.out.println(menuItem);
		}
	}

}

最后测试类,女服务员根据传入的餐厅报菜单,也能完成之前的功能

package iterator.demo;


public class Client
{
    public static void main(String[] args)
    {
        PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
        DinerMenu dinerMenu = new DinerMenu();

        Waitress waitress=new Waitress(pancakeHouseMenu,dinerMenu);
        waitress.printMenu();
    }
}

其实女服务员仍有改进的地方,每次如果新加入一个餐厅,都要修改女服务员里面的内容,这不符合开闭原则

重新优化一下 ,将多个餐厅变成一个餐厅集合,这样每次增加一个餐厅类,就不需要修改女服务员了

package iterator.demo;


import java.util.ArrayList;
import java.util.Iterator;

/**
 * 服务员类,根据餐厅打印菜单
 */
public class Waitress
{
	ArrayList<Menu> menus;

	public Waitress(ArrayList<Menu> menus)
	{
		this.menus = menus;
	}


	public void printMenu() {
		Iterator<Menu> menusIterator = menus.iterator();
		while (menusIterator.hasNext())
		{
			Menu menu = menusIterator.next();
			printMenu(menu.createIterator());
		}

	}

	private void printMenu(Iterator<MenuItem> iterator) {
		while (iterator.hasNext()) {
			MenuItem menuItem = iterator.next();
			System.out.println(menuItem);
		}
	}
}

 测试类要麻烦一点,不过不用修改女服务员,实现了开闭原则

package iterator.demo;

import java.util.ArrayList;

public class Client
{
    public static void main(String[] args)
    {

        PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
        DinerMenu dinerMenu = new DinerMenu();
        ArrayList list = new ArrayList();
        list.add(pancakeHouseMenu);
        list.add(dinerMenu);

        Waitress waitress=new Waitress(list);
        waitress.printMenu();
    }
}
发布了138 篇原创文章 · 获赞 34 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/bbj12345678/article/details/105162657