Design Pattern(8) - Iterator

栏目: 后端 · 发布时间: 8年前

内容简介:Design Pattern(8) - Iterator

以下文章是閱讀 深入淺出Design Pattern 還有 聖經 還有 Source making 的筆記 圖片截圖自lynda.com的 Foundations of Programming: Design Patterns 要更深入的理解一定要去看這兩本書

實作餐廳菜單

今天有一家餐廳A 想用Array來實做一個菜單

public class AMenu{
    static final int MAX_ITEMS = 6;
    int numberOfItems = 0;
    String[] menuItems;
    public AMenu() {
	menuItems = new String[MAX_ITEMS];
	addItem("Vegetarian BLT");
	addItem("BLT");
	addItem("Soup of the day");
	addItem("Hotdog");
	addItem("Steamed Veggies and Brown Rice");
	addItem("Pasta");
    }
  
    public void addItem(String name) 
    {
	if (numberOfItems >= MAX_ITEMS) {
	    System.err.println("Sorry, menu is full!  Can't add item to menu");
	} else {
	    menuItems[numberOfItems] = name;
	    numberOfItems = numberOfItems + 1;
	}
    }
 
    public String[] getMenuItems() {
	return menuItems;
    }
}

今天有個服務生到餐廳A打工 當他需要列出所有選項給客人的時候 他需要這麼做

AMenu amenu = new AMenu();
for(int i = 0; i < amenu.numberOfItems; i++){
    System.out.print(amenu.getMenuItems()[i]);
}

這個服務生很認真 他還同時在另一家餐廳B打工 餐廳B的菜單是用ArrayList實作

public class BMenu{
    ArrayList<String> menuItems;
 
    public BMenu() {
	menuItems = new ArrayList<String>();    
	addItem("K&B's Pancake Breakfast");
	addItem("Regular Pancake Breakfast");
	addItem("Blueberry Pancakes");
	addItem("Waffles");
    }

    public void addItem(String name)
    {
	menuItems.add(name);
    }
 
    public ArrayList<String> getMenuItems() {
	return menuItems;
    } 
}

當他需要列出所有選項給客人的時候

BMenu bmenu = new BMenu();
for(int i = 0; i < bmenu.getMenuItems().size(); i++){
    System.out.print(bmenu.getMenuItems().get(i));
}

嗯…兩個不同餐廳 因為實作方法的不同 client要iterate的用法也不同 挺麻煩的 而且餐廳不一定想讓服務生知道他們的菜單是怎麼實作的(想洩露商業機密)

哎呀 那不是很簡單嗎 把printMenu跟Menu class參在一起不就行了?

Design Pattern(8) - Iterator

每個餐廳 各自 實作自己的printMenu 這樣就不用洩漏實作的訊息給client

public class AMenu{
    //other method...
    public void printMenu(){
	for(int i = 0; i < amenu.numberOfItems; i++){
	    System.out.print(amenu.getMenuItems()[i]);
	}	
    }
}
public class BMenu{
    //other method...
    public void printMenu(){
	for(int i = 0; i < bmenu.getMenuItems().size(); i++){
	    System.out.print(bmenu.getMenuItems().get(i));
	}
    }
}

每個餐廳的menu 各自負責printMenu 這不是解決了嗎?

這時候就要導入一個設計模式中很重要的一個概念

Design Pattern rule #6: Single Responsibility Principle(一個class只負責一件事情)

就如同字面上的意思 每個class只負責做一件事 Menu這個class就只負責addItem 不要負責printMenu

所以我們為每一個菜單 都寫一個相對應的菜單Iterator

public class AMenuIterator{
    String[] items;
    int position = 0;
 
    public AMenuIterator(String[] items) {
	this.items = items;
    }
 
    public String next() {
	String menuItem = items[position];
	position = position + 1;
	return menuItem;
    }
 
    public boolean hasNext() {
	if (position >= items.length || items[position] == null) {
    	    return false;
	} else {
	    return true;
	}
    }
}
public class BMenuIterator {
    ArrayList<String> items;
    int position = 0;
 
    public PancakeHouseMenuIterator(ArrayList<String> items) {
	this.items = items;
    }
 
    public String next() {
	String menuItem = (String) items.get(position);
	position = position + 1;
	return menuItem;
    }
 
    public boolean hasNext() {
 	if (position >= items.size()) {
    	    return false;
	} else {
	    return true;
	}
    }
}

皆大歡喜 現在我printMenu的方法可以適用所有的Iterator 我不需要知道你這家餐廳是怎麼實作你的菜單 你只要給我你的Iterator 我就有辦法print

private static void printMenu(Iterator iterator) {
    while (iterator.hasNext()) {
        String menuItem = (String)iterator.next();
	System.out.println(menuItem);
    }
}

反覆器模式

反覆器模式讓我們可以取得collection內的每一個元素 且不需要知道collection的實作

結構

Design Pattern(8) - Iterator

  • Iterator: 制定Iterator給外界存取的interface 定義遍歷元素的方法

  • ConcreteIterator: 實作Iterator 必須記錄現在存取到哪個元素了

  • Aggregate: 可以想成是任何的Collection 但必須有個函數return 這個Collection的Iterator

  • ConcreteAggregate: 實作Aggregate createIterator函數必須傳回相對應的ConcreateIterator

優缺點

1.Iterator跟Collection分離之後 每個Collection可以有很多的Iterate方式 比如一個Tree有preorder, postorder或inorder traversal 可以愛怎麼實作多少就實作多少 Collection本身毫無負擔

2.可以同時有很多個Iterator在跑 每個Iterator會負責記得跑到哪了

3.Collection的個數和Iterator的個數會成對增加 當你今天想用LinkedList來實作你的菜單 你就需要一個LinkedList的Iterator

願上蒼為你指引平坦的道路

願命運讓你遇見善良的人們

願遠方的陽光和璀璨的燈火

為你照亮每一片未來的天空

汪峰


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Probability and Computing

Probability and Computing

Michael Mitzenmacher、Eli Upfal / Cambridge University Press / 2005-01-31 / USD 66.00

Assuming only an elementary background in discrete mathematics, this textbook is an excellent introduction to the probabilistic techniques and paradigms used in the development of probabilistic algori......一起来看看 《Probability and Computing》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

在线进制转换器
在线进制转换器

各进制数互转换器