Head First(七)--适配器模式与外观模式

包装某些对象:让它们的接口看起来不像自己而像是别的东西。这样的设计,可以将类的接口转换成想要的接口,以便实现不同的接口。另外一个模式,将对象包装起来以简化其接口。
OO适配器和真实世界的适配器扮演着同样的角色;将一个接口转换成另一个接口,以符合客户的期望。

public class MenuItem {
	String name;
	String description;
	boolean vegetarian;
	double price;

	public MenuItem(String name, String description, boolean vegetarian, double price) {
		this.name = name;
		this.description = description;
		this.vegetarian = vegetarian;
		this.price = price;
	}
	//getter and setter
}
public class PancakeHouseMenu {
	ArrayList menuItems;

	public PancakeHouseMenu() {
		menuItems = new ArrayList();
		addItem("K&B's Pancake Breakfast",
				"Pancakes with scrambled eggs, and toast",
				true,
				2.99);

		addItem("Regular Pancake Breakfast",
				"Pancakes with fried eggs, sausage",
				false,
				2.99);

		addItem("Blueberry Pancakes",
				"Pancakes made with fresh blueberries",
				true,
				3.49);

		addItem("Waffles",
				"Waffles, with your choice of blueberries or strawberries",
				true,
				3.59);
	}

	public void addItem(String name, String description, boolean vegetarian, double price) {
		MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
		menuItems.add(menuItem);
	}

	public ArrayList getMenuItems() {
		return menuItems;
	}
}
public class DinerMenu {
	static final int MAX_ITEMS = 6;
	int numberOfItems = 0;
	MenuItem[] menuItems;

	public DinerMenu() {
		menuItems = new MenuItem[MAX_ITEMS];

		addItem("Vegetarian BLT",
				"(Fakin') Bacon with lettuce & tomato on whole wheat", true, 2.99);
		addItem("BLT",
				"Bacon with lettuce & tomato on whole wheat", false, 2.99);
		addItem("Soup of the day",
				"Soup of the day, with a side of potato salad", false, 3.29);
		addItem("Hotdog",
				"A hot dog, with saurkraut, relish, onions, topped with cheese",
				false, 3.05);
		addItem("Steamed Veggies and Brown Rice",
				"Steamed vegetables over brown rice", true, 3.99);
		addItem("Pasta",
				"Spaghetti with Marinara Sauce, and a slice of sourdough bread",
				true, 3.89);
	}

	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("Sorry, menu is full!  Can't add item to menu");
		} else {
			menuItems[numberOfItems] = menuItem;
			numberOfItems++;
		}
	}

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

如果我们要把PancakeHouseMenu和DinerMenu都打印出来的话,需要两种遍历方式,一种list,一种array。

本书的一个原则,封装变化的部分。在这个例子中发生变化的是:由不同集合类型造成的遍历。

现在我们创建一个对象,将它成为迭代器(Iterator),利用它来封装“遍历集合内的每个对象的过程”。

Iterator iterator =breakfastMenu.createIterator();
while (iterator.hasNext()) {
	MenuItem menuItem = (MenuItem) iterator.next();
}
Iterator iterator =lunchMenu.createIterator();
while (iterator.hasNext()) {
	MenuItem menuItem = (MenuItem) iterator.next();
}

这样,遍历的方式就一样了。

迭代器的第一件事情,就是它依赖于一个名为迭代器的接口。

现在,我们对上面两个menu进行改造。

首先,定义一个迭代器

public interface Iterator {
	boolean hasNext();

	Object next();
}
public class DinerMenuIterator implements Iterator {

	MenuItem[] items;
	int position = 0;

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

	@Override
	public boolean hasNext() {
		//因为使用的是固定长度的数组,所以我们不但要检查是否超出了数组长度,
		// 也必须检查是否下一项是null,如果是null,就表示没有其他项了
		if (position >= items.length || items[position] == null) {
			return false;
		} else {
			return true;
		}
	}

	@Override
	public Object next() {
		MenuItem menuItem = items[position];
		position--;
		return menuItem;
	}
}

用迭代器改写餐厅菜单

public class DinerMenu {
	static final int MAX_ITEMS = 6;
	int numberOfItems = 0;
	MenuItem[] menuItems;

	public DinerMenu() {
		menuItems = new MenuItem[MAX_ITEMS];

		addItem("Vegetarian BLT",
				"(Fakin') Bacon with lettuce & tomato on whole wheat", true, 2.99);
		addItem("BLT",
				"Bacon with lettuce & tomato on whole wheat", false, 2.99);
		addItem("Soup of the day",
				"Soup of the day, with a side of potato salad", false, 3.29);
		addItem("Hotdog",
				"A hot dog, with saurkraut, relish, onions, topped with cheese",
				false, 3.05);
		addItem("Steamed Veggies and Brown Rice",
				"Steamed vegetables over brown rice", true, 3.99);
		addItem("Pasta",
				"Spaghetti with Marinara Sauce, and a slice of sourdough bread",
				true, 3.89);
	}

	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("Sorry, menu is full!  Can't add item to menu");
		} else {
			menuItems[numberOfItems] = menuItem;
			numberOfItems++;
		}
	}

	public Iterator createIterator() {
		//客户不需要知道餐厅菜单是如何维护菜单项的,也不需要知道迭代器是如何实现的。
		// 客户只需直接使用这个迭代器遍历菜单项即可
		return new DinerMenuIterator(menuItems);
	}
}
public class PancakeHouseIterator implements Iterator {

	ArrayList items;
	int position = 0;

	public PancakeHouseIterator(ArrayList items) {
		this.items = items;
	}

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

	@Override
	public Object next() {
		Object object = items.get(position);
		position++;
		return object;
	}
}

用迭代器改造PancakeHouseMenu

public class PancakeHouseMenu {
	ArrayList menuItems;

	public PancakeHouseMenu() {
		menuItems = new ArrayList();
		addItem("K&B's Pancake Breakfast",
				"Pancakes with scrambled eggs, and toast",
				true,
				2.99);

		addItem("Regular Pancake Breakfast",
				"Pancakes with fried eggs, sausage",
				false,
				2.99);

		addItem("Blueberry Pancakes",
				"Pancakes made with fresh blueberries",
				true,
				3.49);

		addItem("Waffles",
				"Waffles, with your choice of blueberries or strawberries",
				true,
				3.59);
	}

	public void addItem(String name, String description, boolean vegetarian, double price) {
		MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
		menuItems.add(menuItem);
	}

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

waitress

public class Waitress {
	PancakeHouseMenu pancakeHouseMenu;
	DinerMenu dinerMenu;

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

	public void printMenu() {
		Iterator pancakeIterator = pancakeHouseMenu.createIterator();
		Iterator dinerIterator = dinerMenu.createIterator();
		System.out.println("MENU\n----\nBREAKFAST");
		printMenu(pancakeIterator);
		System.out.println("\nLUNCH");
		printMenu(dinerIterator);
	}

	private void printMenu(Iterator iterator) {
		while (iterator.hasNext()) {
			MenuItem menuItem = (MenuItem) iterator.next();
			System.out.print(menuItem.getName() + ", ");
			System.out.print(menuItem.getPrice() + " -- ");
			System.out.println(menuItem.getDescription());
		}
	}
}

测试:

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

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

结果:


接下来,我们来使用java中的迭代器。

ArrayList有返回迭代器的方法。我们只需要为餐厅菜单实现一个迭代器,因为餐厅菜单使用的是数组,而数组不支持iterator()方法。

删除煎饼屋菜单迭代器类,然后,在煎饼屋菜单的代码前面加上import java.util.Iterator,再改变下面这一行代码就可以了:

public Iterator createIterator() {
	return menuItems.iterator();
}

PancakeHouseMenu就完成了。














  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值