iT邦幫忙

2023 iThome 鐵人賽

0
自我挑戰組

深入淺出設計模式 (Head First Design Pattern) - 重點整理及範例分享系列 第 34

[深入淺出設計模式] Ch9 The iterator and composite patterns (1) - 迭代器模式和組合模式

  • 分享至 

  • xImage
  •  

書中給了一個好懂的範例,假設我們所在的小鎮有兩間有名的餐廳,Pancake House 跟 Diner。
突然有個機會要開一間快閃店,要提供以上兩餐廳的食物分別作為早餐及午餐,但是兩間餐廳的點餐系統略有不同。
其中Pancake House用Java的Arraylist儲存菜單資訊,Diner則是用Java的Array來儲存,兩個餐廳的類別程式碼大致如下:

public class PancakeHouseMenu {
    protected ArrayList<MenuItem> menuItems;

    public void addItem(String name, String descriptions, int price, boolean vegetarian){
        MenuItem item = new MenuItem(name, descriptions, price, vegetarian);
        this.menuItems.add(item);
    }

    public PancakeHouseMenu(){
        this.menuItems = new ArrayList<MenuItem>();
    }

    public ArrayList<MenuItem> getMenuItems(){
        return this.menuItems;
    }
}
public class DinerMenu {
    public static final int MAX_ITEMS = 6;
    public int numOfItems = 0;
    protected MenuItem[] menuItems;

    public void addItem(String name, String descriptions, int price, boolean vegetarian){
        if(this.numOfItems < MAX_ITEMS){
            MenuItem item = new MenuItem(name, descriptions, price, vegetarian);
            this.menuItems[numOfItems] = item;
            numOfItems ++;
        }
        else{
            System.out.println("No extra capacity now");
        }
    }

    public DinerMenu(){
        menuItems = new MenuItem[MAX_ITEMS];
        addItem("Green Delight Set","Mixed greens, avocado, cucumber, tomato, feta", 150, true);
        addItem("Savory Feast Set", "Grilled chicken, mashed potatoes, steamed broccoli", 180, false);
        addItem("Mediterranean Bliss Set", "Hummus, falafel, tabbouleh, pita bread", 160, true);
        addItem("Asian Fusion Set", "Teriyaki tofu, stir-fried vegetables, rice", 170, true);
    }

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

因為資料型態的差異,若是要展示兩份菜單給客人看,就需要用不同的方式去迭代⋯⋯

PancakeHouseMenu PancakeMenu = new PancakeHouseMenu();
ArrayList<MenuItem> breakfastItems = PancakeMenu.getMenuItems();
for(int i = 0 ; i < breakfastItems.size(); i++) {
    MenuItem item = breakfastItems.get(i);
    System.out.println(item.getName());
    System.out.println(item.getPrice());
    System.out.println(item.getDescription()+ "\n");
}
DinerMenu dinerMenu = new DinerMenu();
    int size = dinerMenu.numOfItems;
    MenuItem lunchItems[] = new MenuItem[size];
    lunchItems = dinerMenu.getMenuItems();

    for(int i = 0 ; i < size; i++) {
        MenuItem item = lunchItems[i];
        System.out.println(item.getName());
        System.out.println(item.getPrice());
        System.out.println(item.getDescription()+ "\n");
    }
}   

但是我們需要增加一個 Waiter 的新類別,功能大致如下:

  • printMenu(): prints every item on the menu
  • printBreakfastMenu(): prints just breakfast items
  • printLunchMenu(): prints just lunch items
  • printVegetarianMenu(): prints all vegetarian menu items
  • isItemVegetarian(name):if the items is vegetarian, return true

所以我們希望可以把兩間餐廳的菜單整合起來,這時候就可以用到迭代器模式 Iterator Pattern。
讓我們可以創造新的迭代器介面,將迭代這個功能封裝。以這個例子來說,就是避免之後在拿取不同菜單資料時,還需要去跑分別的迴圈,或是日後加入其他餐廳就會有更多迴圈。

下一篇來詳細實作這個模式~


參考資料:

  1. 《深入淺出設計模式 (Head First Design Patterns) 》
  2. 書中官方程式碼傳送門

Disclaimer
因為讀的是原文版,所以難免會有翻譯詞不達意或是專有名詞上的差異,有錯誤的話歡迎在留言區一起交流!


上一篇
[深入淺出設計模式] Ch8 The Template Method Pattern (2) - 模板模式 範例 動物排序
下一篇
[深入淺出設計模式] Ch9 The iterator and composite patterns (2) - 範例 整合餐廳菜單
系列文
深入淺出設計模式 (Head First Design Pattern) - 重點整理及範例分享35
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言