兩種類型的菜單,第一種菜單中的每一項都是ArrayList的元素,而第二種菜單中的每一項是數(shù)組元素。如何對這兩種菜單統(tǒng)一操作呢?
package javaapplication39;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
PancakeBouseMenu menu = new PancakeBouseMenu();
menu.listMenu();
System.out.println("-----------------------");
DinerMenu menu2 = new DinerMenu();
menu2.listMenu();
}
}
class MenuItem { //菜單中的每一項
String name;
String description;
boolean vegetarian;
int price;
public MenuItem(String name, String description, boolean vegetarian, int price) {
this.name = name;
this.description = description;
this.vegetarian = vegetarian;
this.price = price;
}
String getName() {
return name;
}
String getDescription() {
return description;
}
boolean isVegetarian() {
return vegetarian;
}
int getPrice() {
return price;
}
public void showItem() {
System.out.println(getName() + ":" + getDescription() + " " + getPrice() + " | " + getVegetarian());
}
private String getVegetarian() {
if (isVegetarian() == true) {
return "Is Vegetarian";
}
else {
return "Not Vegetarian";
}
}
}
class PancakeBouseMenu { //第一種方式的菜單,是由ArrayList把每一項連接起來的
ArrayList<MenuItem> menuItems;
MenuItem menuItem;
public PancakeBouseMenu() {
menuItems = new ArrayList<MenuItem>();
addItem("K&B", "Pancake and scrambled", true, 29);
addItem("Waffles", "Waffles with blueberries", true, 39);
addItem("Rregular", "Regular pancake breakefast", false, 10);
}
public void addItem(String name, String description, boolean vegetarian, int price) {
menuItem = new MenuItem(name, description, vegetarian, price);
menuItems.add(menuItem);
}
public void listMenu() {
for (int i = 0; i < menuItems.size(); i++) {
menuItems.get(i).showItem();
}
}
}
class DinerMenu { //第二中方式的菜單,數(shù)組
final int MAX_SIZE = 2;
MenuItem[] menuItems;
int location;
public DinerMenu() {
menuItems = new MenuItem[MAX_SIZE];
location = 0;
addItem("BLT", "Bacon with Lettuce and Tomato", true, 21);
addItem("HotDog", "a hot dog with relish", false, 39);
}
public void addItem(String name, String description, boolean vegetarian, int price) {
if (location < MAX_SIZE) {
menuItems[location] = new MenuItem(name, description, vegetarian, price);
location++;
}
else {
System.out.println("OUT OF MAX_SIZE");
}
}
public void listMenu() {
for (int i = 0; i < MAX_SIZE; i++) {
menuItems[i].showItem();
}
}
}
黃顏色標注的兩個listMenu其實做的事情相同,只是處理的元素種類不同。如果我們還想“列出所有的蔬菜”,“列出所有價格少于XX的菜”。。。那么,DinnerMenu和PancakeMenu里面那又要多出很多相似的方法??刹豢梢苑庋b呢?比如把這些相似的方法寫在它們共同的抽象父類里面,或者放在一個façade類里面?
Iterator pattern 隆重登場:Iterator Pattern是什么?就是為處理各種Collection的類寫一個通用接口。通過一個類似于adapter 的類的中轉,該接口與處理Collection的類相聯(lián)系。
看看下面的程序,注意:我們這個Iterator接口是我們自己寫的,不是java庫里的那個。
package javaapplication39;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
PancakeBouseMenu pmenu = new PancakeBouseMenu();
Iterator iterator = pmenu.createPancakeIterator();
while (iterator.hasNext()) {
iterator.next().showItem();
}
DinerMenu dmenu = new DinerMenu();
iterator = dmenu.createDinnerIterator();
while (iterator.hasNext()) {
iterator.next().showItem();
}
}
}
class MenuItem { //菜單中的每一項
String name;
String description;
boolean vegetarian;
int price;
public MenuItem(String name, String description, boolean vegetarian, int price) {
this.name = name;
this.description = description;
this.vegetarian = vegetarian;
this.price = price;
}
String getName() {
return name;
}
String getDescription() {
return description;
}
boolean isVegetarian() {
return vegetarian;
}
int getPrice() {
return price;
}
public void showItem() {
System.out.println(getName() + ":" + getDescription() + " " + getPrice() + " | " + getVegetarian());
}
private String getVegetarian() {
if (isVegetarian() == true) {
return "Is Vegetarian";
}
else {
return "Not Vegetarian";
}
}
}
interface Iterator {//通用接口
public boolean hasNext();
public MenuItem next();
}
class PancakeIterator implements Iterator {//Adapter和Façade功能的混合體
ArrayList<MenuItem> menuItems;
int location;
PancakeIterator(ArrayList<MenuItem> menuItems) {
this.menuItems = menuItems;
location = 0;
}
public boolean hasNext() {
if (location >= menuItems.size() || menuItems.get(location) == null) {
return false;
}
else {
return true;
}
}
public MenuItem next() {
MenuItem menuItem = menuItems.get(location);
location++;
return menuItem;
}
}
class DinerIterator implements Iterator {
MenuItem[] menuItems;
int location;
DinerIterator(MenuItem[] menuItems) {
this.menuItems = menuItems;
location = 0;
}
public boolean hasNext() {
if (location >= menuItems.length || menuItems[location] == null) { //這個“或”符號的兩邊寫反了,就會拋出數(shù)組越界異常
return false;
}
else {
return true;
}
}
public MenuItem next() {
MenuItem menuItem = menuItems[location];
location++;
return menuItem;
}
}
class PancakeBouseMenu { //第一種方式的菜單,是由ArrayList把每一項連接起來的
ArrayList<MenuItem> menuItems;
public PancakeBouseMenu() {
menuItems = new ArrayList<MenuItem>();
addItem("K&B", "Pancake and scrambled", true, 29);
addItem("Waffles", "Waffles with blueberries", true, 39);
addItem("Rregular", "Regular pancake breakefast", false, 10);
}
public void addItem(String name, String description, boolean vegetarian, int price) {
MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
menuItems.add(menuItem);
}
public Iterator createPancakeIterator() {
return new PancakeIterator(menuItems);
}
}
class DinerMenu { //第二種方式的菜單,數(shù)組
final int MAX_SIZE = 2;
MenuItem[] menuItems;
int location;
public DinerMenu() {
menuItems = new MenuItem[MAX_SIZE];
location = 0;
addItem("BLT", "Bacon with Lettuce and Tomato", true, 21);
addItem("HotDog", "a hot dog with relish", false, 39);
}
public void addItem(String name, String description, boolean vegetarian, int price) {
if (location < MAX_SIZE) {
menuItems[location] = new MenuItem(name, description, vegetarian, price);
location++;
}
else {
System.out.println("OUT OF MAX_SIZE");
}
}
public Iterator createDinnerIterator() {
return new DinerIterator(menuItems);
}
}
最后,我們把DinnerMenu和PancakeMenu中的功能類似的createXXXIterator()方法提取出來,放到新建的接口Menu里面去:
package javaapplication39;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
Menu pmenu = new PancakeBouseMenu();
Iterator iterator = pmenu.createIterator();
while (iterator.hasNext()) {
iterator.next().showItem();
}
Menu dmenu = new DinerMenu();
iterator = dmenu.createIterator();
while (iterator.hasNext()) {
iterator.next().showItem();
}
}
}
class MenuItem { //菜單中的每一項
String name;
String description;
boolean vegetarian;
int price;
public MenuItem(String name, String description, boolean vegetarian, int price) {
this.name = name;
this.description = description;
this.vegetarian = vegetarian;
this.price = price;
}
String getName() {
return name;
}
String getDescription() {
return description;
}
boolean isVegetarian() {
return vegetarian;
}
int getPrice() {
return price;
}
public void showItem() {
System.out.println(getName() + ":" + getDescription() + " " + getPrice() + " | " + getVegetarian());
}
private String getVegetarian() {
if (isVegetarian() == true) {
return "Is Vegetarian";
}
else {
return "Not Vegetarian";
}
}
}
interface Iterator {//通用接口
public boolean hasNext();
public MenuItem next();
}
class PancakeIterator implements Iterator {//Adapter和Façade功能的混合體
ArrayList<MenuItem> menuItems;
int location;
PancakeIterator(ArrayList<MenuItem> menuItems) {
this.menuItems = menuItems;
location = 0;
}
public boolean hasNext() {
if (location >= menuItems.size() || menuItems.get(location) == null) {
return false;
}
else {
return true;
}
}
public MenuItem next() {
MenuItem menuItem = menuItems.get(location);
location++;
return menuItem;
}
}
class DinerIterator implements Iterator {
MenuItem[] menuItems;
int location;
DinerIterator(MenuItem[] menuItems) {
this.menuItems = menuItems;
location = 0;
}
public boolean hasNext() {
if (location >= menuItems.length || menuItems[location] == null) { //這個“或”符號的兩邊寫反了,就會拋出數(shù)組越界異常
return false;
}
else {
return true;
}
}
public MenuItem next() {
MenuItem menuItem = menuItems[location];
location++;
return menuItem;
}
}
interface Menu {
Iterator createIterator();
}
class PancakeBouseMenu implements Menu { //第一種方式的菜單,是由ArrayList把每一項連接起來的
ArrayList<MenuItem> menuItems;
public PancakeBouseMenu() {
menuItems = new ArrayList<MenuItem>();
addItem("K&B", "Pancake and scrambled", true, 29);
addItem("Waffles", "Waffles with blueberries", true, 39);
addItem("Rregular", "Regular pancake breakefast", false, 10);
}
public void addItem(String name, String description, boolean vegetarian, int price) {
MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
menuItems.add(menuItem);
}
public Iterator createIterator() {
return new PancakeIterator(menuItems);
}
}
class DinerMenu implements Menu { //第二種方式的菜單,數(shù)組
final int MAX_SIZE = 2;
MenuItem[] menuItems;
int location;
public DinerMenu() {
menuItems = new MenuItem[MAX_SIZE];
location = 0;
addItem("BLT", "Bacon with Lettuce and Tomato", true, 21);
addItem("HotDog", "a hot dog with relish", false, 39);
}
public void addItem(String name, String description, boolean vegetarian, int price) {
if (location < MAX_SIZE) {
menuItems[location] = new MenuItem(name, description, vegetarian, price);
location++;
}
else {
System.out.println("OUT OF MAX_SIZE");
}
}
public Iterator createIterator() {
return new DinerIterator(menuItems);
}
}
Java中的Collection類型不僅包括數(shù)組,ArrayList,還有hastTable, Queue, 等等。Java API中本身就有自帶的Iterator接口,以及讓這些類型返回一個Iterator型的函數(shù)。只是Java API的Iterator接口不僅有hasnext(), next()函數(shù),還有一個remove()函數(shù)需要子類實現(xiàn)之。
package javaapplication39;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
Menu pmenu = new PancakeBouseMenu();
Iterator iterator = pmenu.createIterator();
while (iterator.hasNext()) {
MenuItem menuItem = (MenuItem) iterator.next();
menuItem.showItem();
}
Menu dmenu = new DinerMenu();
iterator = dmenu.createIterator();
while (iterator.hasNext()) {
MenuItem menuItem = (MenuItem) iterator.next();
menuItem.showItem();
}
Menu cmenu = new CafeMenu();
iterator = cmenu.createIterator();
while (iterator.hasNext()) {
MenuItem menuItem = (MenuItem) iterator.next();
menuItem.showItem();
}
}
}
class MenuItem { //菜單中的每一項
String name;
String description;
boolean vegetarian;
int price;
public MenuItem(String name, String description, boolean vegetarian, int price) {
this.name = name;
this.description = description;
this.vegetarian = vegetarian;
this.price = price;
}
String getName() {
return name;
}
String getDescription() {
return description;
}
boolean isVegetarian() {
return vegetarian;
}
int getPrice() {
return price;
}
public void showItem() {
System.out.println(getName() + ":" + getDescription() + " " + getPrice() + " | " + getVegetarian());
}
private String getVegetarian() {
if (isVegetarian() == true) {
return "Is Vegetarian";
}
else {
return "Not Vegetarian";
}
}
}
class DinerIterator implements Iterator { //數(shù)組不能返回一個Iterator類型,所以只能手寫
MenuItem[] menuItems;
int location;
DinerIterator(MenuItem[] menuItems) {
this.menuItems = menuItems;
location = 0;
}
public boolean hasNext() {
if (location >= menuItems.length || menuItems[location] == null) { //這個“或”符號的兩邊寫反了,就會拋出數(shù)組越界異常
return false;
}
else {
return true;
}
}
public MenuItem next() {
MenuItem menuItem = menuItems[location];
location++;
return menuItem;
}
public void remove() { //Java API中的Iterator還有Remove函數(shù)需要實現(xiàn)
for (int i = location - 1; i < menuItems.length - 1; i++) {
menuItems[i] = menuItems[i + 1];
}
menuItems[menuItems.length - 1] = null;
}
}
interface Menu {
Iterator createIterator();
}
class PancakeBouseMenu implements Menu { //第一種方式的菜單,是由ArrayList把每一項連接起來的
ArrayList<MenuItem> menuItems;
public PancakeBouseMenu() {
menuItems = new ArrayList<MenuItem>();
addItem("K&B", "Pancake and scrambled", true, 29);
addItem("Waffles", "Waffles with blueberries", true, 39);
addItem("Rregular", "Regular pancake breakefast", false, 10);
}
public void addItem(String name, String description, boolean vegetarian, int price) {
MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
menuItems.add(menuItem);
}
public Iterator createIterator() {
return menuItems.iterator(); //直接利用ArrayList中的iterator函數(shù),轉化ArrayList為Iterator型
}
}
class DinerMenu implements Menu { //第二種方式的菜單,數(shù)組
final int MAX_SIZE = 2;
MenuItem[] menuItems;
int location;
public DinerMenu() {
menuItems = new MenuItem[MAX_SIZE];
location = 0;
addItem("BLT", "Bacon with Lettuce and Tomato", true, 21);
addItem("HotDog", "a hot dog with relish", false, 39);
}
public void addItem(String name, String description, boolean vegetarian, int price) {
if (location < MAX_SIZE) {
menuItems[location] = new MenuItem(name, description, vegetarian, price);
location++;
}
else {
System.out.println("OUT OF MAX_SIZE");
}
}
public Iterator createIterator() {
return new DinerIterator(menuItems);//數(shù)組,沒辦法,還是只能手動寫
}
}
class CafeMenu implements Menu {
Hashtable menuItems;
public CafeMenu() {
menuItems = new Hashtable();
addItem("Veggie Burger", "Veggie Burger on a whole bun", true, 30);
addItem("Soup of the Day", "a cup of soap of the day", false, 36);
}
public void addItem(String name, String description, boolean vegetarian, int price) {
MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
menuItems.put(name, menuItem);
}
public Iterator createIterator() {
return menuItems.values().iterator();//HashTable也可以直接轉化成Iterator型
}
}
看到主函數(shù)用到三個同樣的循環(huán),我們把顯示各種Menu的功能放到一個Waitress類中去:
public class Main {
public static void main(String[] args) {
Menu pmenu = new PancakeBouseMenu();
Menu dmenu = new DinerMenu();
Menu cmenu = new CafeMenu();
Waitress waitress = new Waitress();
waitress.printMenu(pmenu, dmenu, cmenu);
}
}
class Waitress {
public void printMenu(Menu pmenu, Menu dmenu, Menu cmenu) {
Iterator iterator = pmenu.createIterator();
while (iterator.hasNext()) {
MenuItem menuItem = (MenuItem) iterator.next();
menuItem.showItem();
}
iterator = dmenu.createIterator();
while (iterator.hasNext()) {
MenuItem menuItem = (MenuItem) iterator.next();
menuItem.showItem();
}
iterator = cmenu.createIterator();
while (iterator.hasNext()) {
MenuItem menuItem = (MenuItem) iterator.next();
menuItem.showItem();
}
}
}
如果我們需要再新添一個TeaMenu呢?那么Waitress里面的printMenu方法的參數(shù)又要添加一個??刹豢梢园阉械?/span>CafeMenu, PancakeMenu, DinnerMenu組成ArrayList,當作參數(shù)傳到printMenu方法里面去呢?
public class Main {
public static void main(String[] args) {
Menu pmenu = new PancakeBouseMenu();
Menu dmenu = new DinerMenu();
Menu cmenu = new CafeMenu();
Waitress waitress = new Waitress();
waitress.addMenuToArrayList(cmenu);
waitress.printMenu();
System.out.println("---------------------------");
waitress.addMenuToArrayList(dmenu);
waitress.addMenuToArrayList(pmenu);
waitress.printMenu();
System.out.println("---------------------------");
waitress.removeMenuToArrayList(cmenu);
waitress.printMenu();
}
}
class Waitress {
ArrayList<Menu> menuList;
public Waitress() {
menuList = new ArrayList<Menu>();
}
public void printMenu() {
for (int i = 0; i < menuList.size(); i++) {
Iterator iterator = menuList.get(i).createIterator();
while (iterator.hasNext()) {
MenuItem menuItem = (MenuItem) iterator.next();
menuItem.showItem();
}
}
}
public void addMenuToArrayList(Menu menu) {
menuList.add(menu);
}
public void removeMenuToArrayList(Menu menu) {
menuList.remove(menu);
}
}