Head First 設計模式 —— 10. 迭代器 (Iterator) 模式

思考題

public void printMenu() {
    PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
    ArrayList breakfastItems = pancakeHouseMenu.getMenuItems();
    
    DinerMenu dinerMenu = new DinerMenu();
    MenuItem[] lunchItems = dinerMenu.getMenuItems();
    
    for (int i = 0; i < breakfastItems.size(); ++i) {
        MenuItem menuItem = (MenuItem) breakfastItems.get(i);
        System.out.print(menuItem.getName() + " ");
        System.out.println(menuItem.getPrice() + " ");
        System.out.println(menuItem.getDescription());
    }
    
    for (int i = 0; i < lunchItems.length; ++i) {
        MenuItem menuItem = lunchItems[i];
        System.out.print(menuItem.getName() + " ");
        System.out.println(menuItem.getPrice() + " ");
        System.out.println(menuItem.getDescription());
    }
}

根據咱們的 printMenu() 實現,下列哪一項爲真? P322java

  • [x] A. 咱們是針對 PancakeHouseMenuDinerMenu 的具體實現編碼,而不是針對接口。git

    • 針對具體實現編程,沒有解耦,沒法動態替換
  • [ ] B. 女招待沒有實現 Java 招待 API ,因此她沒有遵照標準。github

    • 女招待有一個招待規格,算是實現了一個隱式 API,而且內部實現封裝了變化
  • [x] C. 若是咱們決定從 DinerMenu 切換到另外一種菜單,此菜單的項是用 Hashtable 來存放的,咱們會所以須要修改女招待中的許多代碼。編程

    • Hashtable 是一種新的具體實現,須要修改代碼進行適配
  • [x] D. 女招待須要知道每一個菜單如何表達內部的菜單項集合,這違反了封裝。segmentfault

    • 女招待的實現依賴菜單內部實現,與菜單強耦合,沒有封裝變化
  • [x] E. 咱們有重複的代碼; printMenu() 方法須要兩個循環,來遍歷兩種不一樣的菜單。若是咱們加上第三種菜單,咱們就須要第三個循環。框架

    • 因爲是針對菜單項集合的具體實現編程,因此增長新菜單就須要增長循環
  • [ ] F. 這個實現並無基於 MXML(Menu XML),因此就沒有辦法互操做。ide

    • The implementation isn't based on MXML(Menu XML) and so isn't as interoperable as it shoule be.
    • 互操做性(英文:Interoperability;中文又稱爲:協同工做能力,互用性)做爲一種特性,它指的是不一樣的系統和組織機構之間相互合做,協同工做(即互操做)的能力。就軟件而言,互操做性——這條術語用來描述的是不一樣的程序(programs)藉助於同一套交換格式(exchange formats)來交換數據,讀寫相同文件格式(file formats)以及採用相同協議(protocols)的能力。
    • 剛開始不懂,看了維基百科後的解釋後有點似懂非懂。這個實現內部直接處理了不一樣數據格式,具備必定的互操做性。

思考題

請繼續完成 PancakeHouseIterator 的實現,並對 PancakeHouseMenu 類作出必要的修改。 P327this

public class PancakeHouseIterator implements Iterator {
    ArrayList items;
    int position = 0;
    
    public PancakeHouseIterator(ArrayList items) {
        this.items = items;
    }
    
    public Object next() {
        return items.get(position++);
    }
    
    public boolean hasNext() {
        return position >= items.size();
    }
}

public class PancakeHouseMenu {
    ArrayList menuItems;
    
    // 構造器和其餘方法
    // 移除 public ArrayList getMenuItems() 方法
    
    public Iterator createIterator() {
        return new PancakeHouseIterator(menuItems);
    }
}

迭代器模式

提供一種方法順序訪問一個聚合對象中的各個元素,而又不暴露其內部的表示。 P336
迭代器模式編碼

特色
  • 遍歷集合內部元素而不暴露內部表示 P336
  • 讓聚合的接口和實現變得簡潔 P336
  • 管理對象集合,沒必要理會遍歷的事情 P336

思考題

迭代器模式的類圖看起來很像咱們所學過的另外一個模式;你知道是哪一個模式嗎?提示:子類決定要建立哪一個對象。 P337idea

  • 工廠方法模式

設計原則

單一職責原則:一個類應該只有一個引發變化的緣由 P339

  • 高內聚:一個模塊或一個類只支持一組相關的功能 P339
特色
  • 儘可能將一個責任只指派給一個類 P339
  • 遵循單一職責原則的類是高內聚的 P339

思考題

請很快寫下爲了能讓咖啡廳的菜單代碼符合咱們的框架,咱們要對它作的三件事情: P342

public class CafeMenu {
    HashTable menuItems = new Hashtable(); 
    
    public CafeMenu() {
        // 省略下述參數
        // addItem(...);
        // addItem(...);
        // addItem(...);
    }
    
    public void addItem(String name, String description, boolean vegetarian, double price) {
        MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
        menuItems.put(menuItem.getName(), menuItem);
    }
    
    public Hashtable getItems() {
        return menuItems;
    }
}
  • 實現 Menu 接口
  • 刪除 getItems() 方法
  • 增長 createIterator() 方法
本文首發於公衆號:滿賦諸機( 點擊查看原文) 開源在 GitHub : reading-notes/head-first-design-patterns
相關文章
相關標籤/搜索