频道栏目
首页 > 资讯 > 其他 > 正文

《HeadFirst设计模式》读书笔记-第9章-迭代器模式

17-04-24        来源:[db:作者]  
收藏   我要投稿

定义

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

迭代器模式把遍历集合内元素的操作交给了迭代器,而集合本身专注在管理元素,这符合单一责任原则,让设计具有高内聚。

这里写图片描述

代码实现

下面以JDK现有的Iterator的例子来说明适配器模式使用。

给出创建Iterator接口的定义:

import java.util.Iterator;

public interface Menu {

public Iterator createIterator();

}

菜单项的BEAN对象:

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;

}

public String getName() {

return name;

}

public String getDescription() {

return description;

}

public double getPrice() {

return price;

}

public boolean isVegetarian() {

return vegetarian;

}

}

具体集合对象,管理(增加,移除,查找等)集合的元素,实现创建Iterator接口

import java.util.ArrayList;

import java.util.Iterator;

public class PancakeHouseMenu implements Menu {

ArrayList menuItems; // 内部存储是ArrayList

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, and blueberry syrup",

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 Iterator createIterator() {

return menuItems.iterator();

}

// other menu methods here

}

另一个具体集合对象,内部的存储是数组

import java.util.Iterator;

public class DinerMenu implements Menu {

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",

"A medly of 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 = numberOfItems + 1;

}

}

public MenuItem[] getMenuItems() {

return menuItems;

}

// 数组需要自己实现迭代器的创建

public Iterator createIterator() {

return new DinerMenuIterator(menuItems);

}

// other menu methods here

}

数组类型的迭代器的实现:

import java.util.Iterator; // 使用JDK中迭代器接口

public class DinerMenuIterator implements Iterator {

MenuItem[] list;

int position = 0;

public DinerMenuIterator(MenuItem[] list) {

this.list = list;

}

public Object next() {

MenuItem menuItem = list[position];

position = position + 1;

return menuItem;

}

public boolean hasNext() {

if (position >= list.length || list[position] == null) {

return false;

} else {

return true;

}

}

public void remove() {

if (position <= 0) {

throw new IllegalStateException

("You can't remove an item until you've done at least one next()");

}

if (list[position-1] != null) {

for (int i = position-1; i < (list.length-1); i++) {

list[i] = list[i+1];

}

list[list.length-1] = null;

}

}

}

另一个具体集合对象,内部的存储是Hashtable

import java.util.*;

public class CafeMenu implements Menu {

Hashtable menuItems = new Hashtable(); //内部的存储是Hashtable

public CafeMenu() {

addItem("Veggie Burger and Air Fries",

"Veggie burger on a whole wheat bun, lettuce, tomato, and fries",

true, 3.99);

addItem("Soup of the day",

"A cup of the soup of the day, with a side salad",

false, 3.69);

addItem("Burrito",

"A large burrito, with whole pinto beans, salsa, guacamole",

true, 4.29);

}

public void addItem(String name, String description,

boolean vegetarian, double price)

{

MenuItem menuItem = new MenuItem(name, description, vegetarian, price);

menuItems.put(menuItem.getName(), menuItem);

}

public Hashtable getItems() {

return menuItems;

}

public Iterator createIterator() {

return menuItems.values().iterator();

}

}

客户(招待员)代码,她持有Menu接口,通过这个接口去创建迭代器遍历菜单,她不需要知道菜单项内部的存储细节。

import java.util.Iterator;

public class Waitress {

Menu pancakeHouseMenu; // 煎饼屋菜单

Menu dinerMenu; // 餐厅菜单

Menu cafeMenu; // 咖啡厅菜单

public Waitress(Menu pancakeHouseMenu, Menu dinerMenu, Menu cafeMenu) {

this.pancakeHouseMenu = pancakeHouseMenu;

this.dinerMenu = dinerMenu;

this.cafeMenu = cafeMenu;

}

public void printMenu() {

// 生成迭代器接口

Iterator pancakeIterator = pancakeHouseMenu.createIterator();

Iterator dinerIterator = dinerMenu.createIterator();

Iterator cafeIterator = cafeMenu.createIterator();

System.out.println("MENU\n----\nBREAKFAST");

printMenu(pancakeIterator);

System.out.println("\nLUNCH");

printMenu(dinerIterator);

System.out.println("\nDINNER");

printMenu(cafeIterator);

}

// 遍历迭代器,遍历所有迭代器的代码都可以复用这段代码

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 void printVegetarianMenu() {

System.out.println("\nVEGETARIAN MENU\n---------------");

printVegetarianMenu(pancakeHouseMenu.createIterator());

printVegetarianMenu(dinerMenu.createIterator());

printVegetarianMenu(cafeMenu.createIterator());

}

public boolean isItemVegetarian(String name) {

Iterator pancakeIterator = pancakeHouseMenu.createIterator();

if (isVegetarian(name, pancakeIterator)) {

return true;

}

Iterator dinerIterator = dinerMenu.createIterator();

if (isVegetarian(name, dinerIterator)) {

return true;

}

Iterator cafeIterator = cafeMenu.createIterator();

if (isVegetarian(name, cafeIterator)) {

return true;

}

return false;

}

private void printVegetarianMenu(Iterator iterator) {

while (iterator.hasNext()) {

MenuItem menuItem = (MenuItem)iterator.next();

if (menuItem.isVegetarian()) {

System.out.print(menuItem.getName() + ", ");

System.out.print(menuItem.getPrice() + " -- ");

System.out.println(menuItem.getDescription());

}

}

}

private boolean isVegetarian(String name, Iterator iterator) {

while (iterator.hasNext()) {

MenuItem menuItem = (MenuItem)iterator.next();

if (menuItem.getName().equals(name)) {

if (menuItem.isVegetarian()) {

return true;

}

}

}

return false;

}

}

测试驱动代码

import java.util.*;

public class MenuTestDrive {

public static void main(String args[]) {

//

Menu pancakeHouseMenu = new PancakeHouseMenu();

Menu dinerMenu = new DinerMenu();

Menu cafeMenu = new CafeMenu();

Waitress waitress = new Waitress(pancakeHouseMenu, dinerMenu, cafeMenu);

// 各种遍历菜单的方式

waitress.printMenu();

waitress.printVegetarianMenu();

System.out.println("\nCustomer asks, is the Hotdog vegetarian?");

System.out.print("Waitress says: ");

if (waitress.isItemVegetarian("Hotdog")) {

System.out.println("Yes");

} else {

System.out.println("No");

}

System.out.println("\nCustomer asks, are the Waffles vegetarian?");

System.out.print("Waitress says: ");

if (waitress.isItemVegetarian("Waffles")) {

System.out.println("Yes");

} else {

System.out.println("No");

}

}

}

从上面的代码可以看出,迭代器让客户遍历集合的代码更加通用,它不用关心集合内部的存储细节,因为集合对象创建的迭代器封装了遍历具体数据结构的细节。

 

相关TAG标签
上一篇:Android数据库的学习(一)
下一篇:Android中EditText的inputType属性的详解
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站