`
king_tt
  • 浏览: 2114635 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

【设计模式】学习笔记12:迭代器模式(Iterator)

 
阅读更多



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



走进迭代器模式

迭代器几乎是最常用的一种设计模式,在各面向对象语言中都有实现。


1. 迭代器首先需要一个迭代器的接口:


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类现在只使用一个接口(迭代器)




定义迭代器模式

迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而不是暴露出其内部的表示。


迭代器模式能够让我们游走于聚合内的没一个元素,而又不暴露其内部的表示

把游走的任务放在迭代器上,而不是聚合上。这样简化了聚合的接口和实现,也让责任各得其所。



设计原则:单一责任

一个类应该只有一个引起变化的原因


我们知道要避免类内的改变,因为修改代码很容易造成许多潜在的错误。如果一个类具有两个改变的原因,那么这会使得将来该类的变化几率上升,而当它真的改变时,你的设计中同时有两个方面将会受到影响




内聚:用来度量一个类或模板紧密地达到单一目的或责任。当一个模板或一个类设计只支持一组相关的功能时,我们说它具有高内聚;反之具有低内聚。


迭代器意味着没有次序。只是取出所有的元素,并不表示取出元素的先后就代表元素的大小次序。对于迭代器来说,数据结构可以是有次序的,也可以是没有次序的,甚至数据可以是重复。除非某些集合有特别说明,否则不对迭代器取出的元素大小次序作出假设







分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics