【设计模式】9. 迭代器模式

引子

例如Waitress类要遍历打印两种菜单,一种是基于ArrayList,一种是基于数组;

则Waitress需要对他们分别用两个不同的逻辑来遍历。


定义

Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.

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


类图

【设计模式】9. 迭代器模式_第1张图片

1、Iterator:抽象迭代器

这是所有迭代器都必须实现的接口,利用该接口方法可以在集合元素之间游走。可用java.util.Iterator

2、ConcreteIterator:具体迭代器

具体迭代器负责管理目前遍历的位置、完成集合元素的遍历。

public class DinerMenuIterator implements Iterator {
    MenuItem[] list;
    int position = 0; //记录当前遍历位置
    
    public DinerMenuIterator(MenuItem[] list){
        this.list = list
    }

    public Object next(){
        MenuItem menuItem = list[position];
        position = position + 1;
        return menuItem;  
    }

    public boolean hasNext(){
        if (position >= list.length || list[position] == null){
            return false;
        } else {
            return true;
        }
    }
}

3、Aggregate:抽象聚合(集合)

是对具体集合类的抽象,方便客户端代码,将客户端代码从具体集合对象中解耦——让客户端:针对接口编程,而不针对实现编程

4、ConcreteAggregate:具体聚合(集合)

实现createIterator(),返回一个ConcreteIterator对象;该迭代器对象能够遍历对象集合。

public class DinerMenu {
    MenuItem[] menuItems;
    //返回迭代器接口
    public Iterator createIterator {
        return new DinerMenuIterator( menuItems );
    }
    //这个方法不再需要,因为会暴露内部实现!!
    public MenuItem[] getMenuItem(){
        return menuItems;
    }
}

优点

  1. 让客户遍历你的对象,而又无法窥视你存储对象的方式
  2. Iterator封装“遍历集合内每个对象的过程”;——将遍历的任务放在迭代器上,而不是集合上;简化了集合的接口和实现,也让责任各得其所(单一职责原则 > 高内聚)
  3. 每种ConcreteAggregate集合的内部实现可能不同,但遍历方法都统一起来了,方便客户端代码。——客户端代码与集合实现类解耦。


缺点


使用场景

尽量不要自己写迭代器模式。使用Java提供的Iterator一般就足够了。


注:上例中是数组,所以自己写了个Iterator;如果是ArrayList则直接使用.iterator()即可!





你可能感兴趣的:(设计模式)