上篇講完這個範例的需求,簡單來說我們現在要寫一個通用的介面Iterator
,讓Waiter
可以方便取得不同資料型態儲存資料的餐廳菜單資訊,用統一的方式去迭代資料。
首先就是介面Iterator
:
public interface Iterator {
// 判斷陣列是否有下一個要迭代的物件
public boolean hasNext();
// 回傳目前迭代的物件,並讓迭代繼續
public Object next();
}
DinerMenu
實作Iterator
後的結果:
public class DinerIterator implements Iterator{
// 以陣列儲存資料
protected MenuItem menuItems[];
// 目前迭代的位置(編號)
protected int position;
protected int numOfItems;
public DinerIterator(MenuItem []menuItems, int numOfItems){
this.menuItems = menuItems;
this.numOfItems = numOfItems;
position = 0;
}
public boolean hasNext(){
if(position < numOfItems || menuItems[position] != null){
return true;
}
return false;
}
public MenuItem next(){
MenuItem nextItem = this.menuItems[position];
position ++;
return nextItem;
}
}
類別DinerMenu
要增加以下方法才能進行迭代
public DinerIterator createIterator(){
return new DinerIterator(menuItems, numOfItems);
}
public boolean hasNext(){
if(this.position < numOfItems || this.menuItems[position] != null){
return true;
}
return false;
}
public MenuItem next(){
MenuItem nextItem = this.menuItems[position];
position ++;
return nextItem;
}
另一邊的DinerMenu
是用java的類別ArrayList來儲存資料,而ArrayList本身就有函數iterator()
可以回傳一個iterator,所以不需要去實作我們自己定義的介面Iterator()
,只要新增以下方法即可:
public ArrayList<MenuItem> getMenuItems(){
return this.menuItems;
}
public Iterator<MenuItem> createIterator(){
return menuItems.iterator();
}
最重要的Waiter()
就是要去實作這些迭代邏輯的類別(給客人看指定的菜單):
public class Waiter {
DinerMenu dinerMenu;
PancakeHouseMenu pancakeHouseMenu;
public Waiter(DinerMenu dinerMenu, PancakeHouseMenu pancakeHouseMenu){
this.dinerMenu = dinerMenu;
this.pancakeHouseMenu = pancakeHouseMenu;
}
// 印出 PancakeHouseMenu
public void showBreakfastMenu(){
System.out.println("PancakeHouse Menu:");
java.util.Iterator<MenuItem> pancakeIter = this.pancakeHouseMenu.createIterator();
// java的類別Iterator就有hasNext()、next()的方法可以用
while(pancakeIter.hasNext()){
MenuItem item = pancakeIter.next();
String vegan = "(X)";
if(item.isVegetarian()){
vegan = "(V)";
}
System.out.println(item.getName() + " - $" + item.getPrice() + vegan);
}
}
// 印出DinerMenu
public void showLunchMenu(){
DinerIterator dinerIter = this.dinerMenu.createIterator();
System.out.println("Diner Menu:");
// 實作DinerIterator的hasNext()、next()方法
while(dinerIter.hasNext()){
MenuItem item = dinerIter.next();
String vegan = "(X)";
if(item.isVegetarian()){
vegan = "(V)";
}
System.out.println(item.getName() + " - $" + item.getPrice() + vegan);
}
}
public void showMenus(){
System.out.println("< Menu >");
showBreakfastMenu();
System.out.println("--------------------");
showLunchMenu();
}
public void showVegetarianMenus(){
System.out.println("< Vegan Menu >");
System.out.println("PancakeHouse Menu:");
java.util.Iterator<MenuItem> pancakeIter = this.pancakeHouseMenu.createIterator();
while(pancakeIter.hasNext()){
MenuItem item = pancakeIter.next();
if(item.isVegetarian()){
System.out.println(item.getName() + " - $" + item.getPrice());
}
}
System.out.println("--------------------");
DinerIterator dinerIter = this.dinerMenu.createIterator();
System.out.println("Diner Menu:");
while(dinerIter.hasNext()){
MenuItem item = dinerIter.next();
if(item.isVegetarian()){
System.out.println(item.getName() + " - $" +item.getPrice());
}
}
}
}
最後來實際跑一次看看結果:
public static void main(String arg[]){
PancakeHouseMenu pancakeMenu = new PancakeHouseMenu();
DinerMenu dinerMenu = new DinerMenu();
Waiter Amy = new Waiter(dinerMenu, pancakeMenu);
Amy.showMenus();
Amy.showVegetarianMenus();
}
輸出:
Disclaimer
因為讀的是原文版,所以難免會有翻譯詞不達意或是專有名詞上的差異,有錯誤的話歡迎在留言區一起交流!