有許多種方法能夠把對象堆起來成爲一個集合
好消息,當地的餐廳和煎餅屋合併了,可是二者實現的方式卻不一樣,這就形成了分歧。讓咱們一塊兒去看看把。
java
一個使用ArrayList集合,另外一個使用數組實現,事情看起來確實棘手,咱們建立一個女招待做爲中間人來使用兩個菜單的客戶代碼
編程
這裏就有個問題,咱們在打印早餐和午飯的時候因爲使用對象不一樣,Arraylist和數組,這樣咱們就要寫兩個for循環了,假若後面還有新的對象加進來作晚餐呢?或許咱們能想出一個辦法,讓他們的菜單實現一個相同的接口,咱們是否能夠試着封裝多個遍歷呢?步驟圖以下
設計模式
OK,看來迭代器模式幫助了咱們,迭代器(iterator)依賴於迭代器接口。相關類圖以下
數組
想要在餐廳菜單中加入迭代器,咱們先定義迭代器接口ide
package MenuItem; /** * 迭代器接口 * * @author Joy * */ public interface Iterator { // 知道是否還有更多元素 boolean hasNext(); // 返回下一個元素 Object next(); }
而後先用DinerMenuIterator類去實現接口測試
package MenuItem; /** * 實現迭代器 * * @author Joy * */ public class DinerMenuIterator implements Iterator { MenuItem[] items; int position = 0;// 數組索引 // 構造器初始化傳入一個菜單項的數組當參數 public DinerMenuIterator(MenuItem[] items) { this.items = items; } // 返回數組下一項,索引自+1 @Override public Object next() { MenuItem menuItem = items[position]; position += 1; return menuItem; } // 判斷數組是否滿了 @Override public boolean hasNext() { if (position >= items.length || items[position] == null) { return false; } return true; } }
咱們有了菜單迭代器,利用它改寫餐廳菜單,DineMenu類中這樣寫this
package MenuItem; /** * 對象村餐廳 * * @author Joy * */ public class DineMenu { // 菜單總數 static final int MAX_ITEMS = 6; // 菜單量 int numberOfItems = 0; MenuItem[] menuItems; // 初始化數組,添加菜單內容 public DineMenu() { menuItems = new MenuItem[MAX_ITEMS]; addItem("素食BLT", "(煎)培根、生菜&西紅柿並用麪包作", true, 2.99); addItem("BLT", "培根、生菜&西紅柿", false, 2.99); addItem("例湯", "一碗例湯、配土豆沙拉", false, 3.29); addItem("熱狗", "熱狗、酸菜、上蓋芝士", false, 3.29); addItem("清蒸時蔬加糙米", "清蒸的蔬菜配糙米", false, 3.05); } // 建立一個添加菜單方法 public void addItem(String name, String description, boolean vegetarian, double price) { MenuItem menuItem = new MenuItem(name, description, vegetarian, price); if (numberOfItems >= MAX_ITEMS) { System.out.println("抱歉,菜單已滿,不能添加菜單了"); } else { // 菜單還沒滿還能夠繼續添加 menuItems[numberOfItems] = menuItem; numberOfItems += 1; } } // 使用迭代器遍歷菜單 public Iterator createIterator() { return new DinerMenuIterator(menuItems); } }
完整代碼以下
spa
迭代器接口設計
package MenuItem; /** * 迭代器接口 * * @author Joy * */ public interface Iterator { // 知道是否還有更多元素 boolean hasNext(); // 返回下一個元素 Object next(); }
菜單類code
package MenuItem; /** * 對象村餐廳 * * @author Joy * */ public class DineMenu { // 菜單總數 static final int MAX_ITEMS = 6; // 菜單量 int numberOfItems = 0; MenuItem[] menuItems; // 初始化數組,添加菜單內容 public DineMenu() { menuItems = new MenuItem[MAX_ITEMS]; addItem("素食BLT", "(煎)培根、生菜&西紅柿並用麪包作", true, 2.99); addItem("BLT", "培根、生菜&西紅柿", false, 2.99); addItem("例湯", "一碗例湯、配土豆沙拉", false, 3.29); addItem("熱狗", "熱狗、酸菜、上蓋芝士", false, 3.29); addItem("清蒸時蔬加糙米", "清蒸的蔬菜配糙米", false, 3.05); } // 建立一個添加菜單方法 public void addItem(String name, String description, boolean vegetarian, double price) { MenuItem menuItem = new MenuItem(name, description, vegetarian, price); if (numberOfItems >= MAX_ITEMS) { System.out.println("抱歉,菜單已滿,不能添加菜單了"); } else { // 菜單還沒滿還能夠繼續添加 menuItems[numberOfItems] = menuItem; numberOfItems += 1; } } // 使用迭代器遍歷菜單 public Iterator createIterator() { return new DinerMenuIterator(menuItems); } }
餐廳的實現以及接口
package MenuItem; /** * 實現迭代器 * * @author Joy * */ public class DinerMenuIterator implements Iterator { MenuItem[] items; int position = 0;// 數組索引 // 構造器初始化傳入一個菜單項的數組當參數 public DinerMenuIterator(MenuItem[] items) { this.items = items; } // 返回數組下一項,索引自+1 @Override public Object next() { MenuItem menuItem = items[position]; position += 1; return menuItem; } // 判斷數組是否滿了 @Override public boolean hasNext() { if (position >= items.length || items[position] == null) { return false; } return true; } }
package MenuItem; /** * 對象村餐廳 * * @author Joy * */ public class DineMenu { // 菜單總數 static final int MAX_ITEMS = 6; // 菜單量 int numberOfItems = 0; MenuItem[] menuItems; // 初始化數組,添加菜單內容 public DineMenu() { menuItems = new MenuItem[MAX_ITEMS]; addItem("素食BLT", "(煎)培根、生菜&西紅柿並用麪包作", true, 2.99); addItem("BLT", "培根、生菜&西紅柿", false, 2.99); addItem("例湯", "一碗例湯、配土豆沙拉", false, 3.29); addItem("熱狗", "熱狗、酸菜、上蓋芝士", false, 3.29); addItem("清蒸時蔬加糙米", "清蒸的蔬菜配糙米", false, 3.05); } // 建立一個添加菜單方法 public void addItem(String name, String description, boolean vegetarian, double price) { MenuItem menuItem = new MenuItem(name, description, vegetarian, price); if (numberOfItems >= MAX_ITEMS) { System.out.println("抱歉,菜單已滿,不能添加菜單了"); } else { // 菜單還沒滿還能夠繼續添加 menuItems[numberOfItems] = menuItem; numberOfItems += 1; } } // 使用迭代器遍歷菜單 public Iterator createIterator() { return new DinerMenuIterator(menuItems); } }
同理煎餅屋的實現和接口
package MenuItem; import java.util.ArrayList; public class PancakeHouseIterator implements Iterator { ArrayList items; int position = 0; public PancakeHouseIterator(ArrayList items) { this.items = items; } @Override public Object next() { Object obj = items.get(position); position += 1; return obj; } @Override public boolean hasNext() { if (position >= items.size()) { return false; } return true; } }
package MenuItem; import java.util.ArrayList; /** * 對象村煎餅屋菜單 * * @author Joy * */ public class PancakeHouseMenu { ArrayList menuItems; public PancakeHouseMenu() { menuItems = new ArrayList(); addItem("K&B薄煎餅早餐", "薄煎餅,清蛋和吐司", true, 2.99); addItem("薄煎餅早餐例餐", "薄煎餅,煎蛋和香腸", false, 2.99); addItem("藍莓薄煎餅", "新鮮藍莓和藍莓糖漿作成的薄煎餅", false, 3.49); addItem("鬆餅", "能夠選擇藍莓或草莓", true, 3.59); } // 建立一個添加菜單方法 public void addItem(String name, String description, boolean vegetarian, double price) { // 菜單項對象,並加入到ArrayList裏 MenuItem menuItem = new MenuItem(name, description, vegetarian, price); menuItems.add(menuItem); } //使用迭代器遍歷菜單 public Iterator createIterator(){ return new PancakeHouseIterator(menuItems); } }
女招待的實現
package MenuItem; /** * 對象村的女招待 * * @author Joy * */ public class Waitress { //建立兩個餐廳對象的引用 PancakeHouseMenu pancakeHouseMenu; DineMenu dineMenu; // 初始化兩個菜單 public Waitress(PancakeHouseMenu pancakeHouseMenu, DineMenu dineMenu) { this.dineMenu = dineMenu; this.pancakeHouseMenu = pancakeHouseMenu; } public void printMenu() { // 爲每個菜單建立一個迭代器 Iterator pancakeitIterator = pancakeHouseMenu.createIterator(); Iterator dinerIterator = dineMenu.createIterator(); System.out.println("Menu\n=======\nBreakFast"); // 調用下面重載的方法 printMenus(pancakeitIterator); System.out.println("\nLunch"); // 調用下面重載的方法 printMenus(dinerIterator); } // 重載一個printMenu()方法 // 使用迭代器(一次循環便可)來遍歷菜單項並打印出來,只調用Iterator接口 public void printMenus(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()); } } }
測試類
package TestMain; import MenuItem.DineMenu; import MenuItem.PancakeHouseMenu; import MenuItem.Waitress; public class MenuTestDrive { public static void main(String[] args) { PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu(); DineMenu dineMenu = new DineMenu(); /** *兩個菜單都實現同樣的方法,可是並無實現相同的接口, *女招待仍是要依賴兩個具體實現的菜單類 *後面就要修改這裏 * */ Waitress waitress = new Waitress(pancakeHouseMenu, dineMenu); waitress.printMenu(); } }
效果圖以下
很巧妙的將二者迭代取出來了。但二者實現的接口卻徹底同樣,這裏其實還能夠抽象出來成一個共同接口。
感謝你看到這裏,迭代器模式上部分到這裏就結束了,本人文筆隨便,如有不足或錯誤之處望給予指點,90度彎腰~~~很快我會補全這個內容,生命不息,編程不止!
參考書籍《Head First設計模式》