天天看點

【設計模式】學習筆記12:疊代器模式(Iterator)

本文出自   http://blog.csdn.net/shuangde800

走進疊代器模式

疊代器幾乎是最常用的一種設計模式,在各面向對象語言中都有實作。

1.  疊代器首先需要一個疊代器的接口:

【設計模式】學習筆記12:疊代器模式(Iterator)
public interface Iterator {
    boolean hasNext(); // 會傳回一個布爾值,讓我們知道是否還有更多的元素
    Object next();  // next()方法會傳回下一個元素
}
           

一旦我們有了這個接口,就可以為各種對象集合實作疊代器:數組,清單,散清單……

2. 封裝一個數組的疊代器,并且假設這個數組是給某個餐廳的菜單服務:

public class DinerMenuIterator implements Iterator {
    MenuItem[] items;
    int position = 0;
    public DinerMenuIterator(MenuItem[] items) {
        this.items = items;
    }
    // next()方法傳回數組内的下一項,并遞增其位置
    public Object next() {
        MenuItem menuItem = items[position];
        position = position + 1;
        return menuItem;
    }
    // hasNext()方法會檢查我們是否已經取得數組内的所有元素
    public boolean hasNext() {
        if (position >= items.length || items[position] == null) {
            return false;
        } else {
            return true;
        }
    }
}
           

3. 把疊代器組合進菜單。  

public class DinerMenu implements Menu {
    static final int MAX_ITEMS = 6;
    int numberOfItems = 0;
    MenuItem[] menuItems;
  
    public DinerMenu() {
        menuItems = new MenuItem[MAX_ITEMS];
    }
  
    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
}
           

5. 我們要列印出這個菜單的内容,隻需要擷取它的疊代器即可周遊出所有的菜單項,并且輸出:

public class Waitress {

    // 這個方法為每個菜單各自建立一個疊代器
    public void printMenu() {
        Iterator dinerIterator = dinerMenu.createIterator(); // 擷取疊代器
        printMenu(dinerIterator); // 調用printMenu周遊疊代器輸出内容
    }
 
    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());
        }
    }
}
           

通過引入疊代器,菜單的實作已經被封裝起來,Waitress類不知道菜單是如何存儲菜單項集合的。

有了疊代器,我們隻需要一個循環,就可以多态地處理任何項的集合。

而且Waitress類現在隻使用一個接口(疊代器)

定義疊代器模式

疊代器模式提供一種方法順序通路一個聚合對象中的各個元素,而不是暴露出其内部的表示。

疊代器模式能夠讓我們遊走于聚合内的沒一個元素,而又不暴露其内部的表示

把遊走的任務放在疊代器上,而不是聚合上。這樣簡化了聚合的接口和實作,也讓責任各得其所。

設計原則:單一責任

一個類應該隻有一個引起變化的原因

我們知道要避免類内的改變,因為修改代碼很容易造成許多潛在的錯誤。如果一個類具有兩個改變的原因,那麼這會使得将來該類的變化幾率上升,而當它真的改變時,你的設計中同時有兩個方面将會受到影響

【設計模式】學習筆記12:疊代器模式(Iterator)

内聚:用來度量一個類或模闆緊密地達到單一目的或責任。當一個模闆或一個類設計隻支援一組相關的功能時,我們說它具有高内聚;反之具有低内聚。

疊代器意味着沒有次序。隻是取出所有的元素,并不表示取出元素的先後就代表元素的大小次序。對于疊代器來說,資料結構可以是有次序的,也可以是沒有次序的,甚至資料可以是重複。除非某些集合有特别說明,否則不對疊代器取出的元素大小次序作出假設

繼續閱讀