迭代器模式

127 阅读2分钟

目的

实现数据存储和数据遍历分离。

定义

提供一种方法来访问聚合对象,而不用暴露这个对象的内部表示。

角色

Iterator(抽象迭代器)

定义了访问和遍历元素的接口

public interface AbstractIterator {
    void next(); //移至下一个元素

    boolean isLast(); //判断是否为最后一个元素

    void previous(); //移至上一个元素

    boolean isFirst(); //判断是否为第一个元素

    Object getNextItem(); //获取下一个元素

    Object getPreviousItem();
}

ConcreteIterator(具体迭代器)

实现了抽象迭代器接口

public class ProductIterator implements AbstractIterator {

    private ProductList productList;
    private List products;
    private int cursor1;
    private int cursor2;

    public ProductIterator(ProductList productList) {
        this.productList = productList;
        this.products = productList.getObjects();
        cursor1 = 0;
        cursor2 = products.size() - 1;
    }

    @Override
    public void next() {
        if (cursor1 < products.size()) {
            cursor1++;
        }
    }

    @Override
    public boolean isLast() {
        return (cursor1 == products.size());
    }

    @Override
    public void previous() {
        if (cursor2 > -1) {
            cursor2--;
        }
    }

    @Override
    public boolean isFirst() {
        return (cursor2 == -1);
    }

    @Override
    public Object getNextItem() {
        return products.get(cursor1);
    }

    @Override
    public Object getPreviousItem() {
        return products.get(cursor2);
    }
}

Aggregate(抽象聚合类)

用于存储和管理元素对象,声明一个createIterator()方法用于 创建一个迭代器对象,充当抽象迭代器工厂角色。

public abstract class AbstractObjectList {
    protected List<Object> objects =new ArrayList<>();

    public AbstractObjectList(List<Object> objects) {
        this.objects = objects;
    }

    public void addObject(Object object){
        this.objects.add(object);
    }

    public void removeObject(Object object){
        this.objects.remove(object);
    }

    public List getObjects(){
        return this.objects;
    }

    public abstract AbstractIterator createIterator();
}

ConcreteAggregate(具体聚合类)

实现了在抽象聚合类中声明的createIterator()方法,该 方法返回一个与该具体聚合类对应的具体迭代器ConcreteIterator实例。

public class ProductList extends AbstractObjectList {

    public ProductList(List products) {
        super(products);
    }

    @Override
    public AbstractIterator createIterator() {
        return new ProductIterator(this);
    }
}

客户类

public class IteratorClient {
    public static void main(String[] args) {
        List lists = new ArrayList();
        lists.add("AA");
        lists.add("BB");
        lists.add("CC");
        lists.add("DD");
        lists.add("EE");

        AbstractObjectList list;
        AbstractIterator iterator;

        list = new ProductList(lists);
        iterator = list.createIterator();

        System.out.println("正向遍历:");
        while (!iterator.isLast()) {
            System.out.print(iterator.getNextItem() + ",");
            iterator.next();
        }

        System.out.println();

        System.out.println("反向遍历:");
        while (!iterator.isFirst()) {
            System.out.print(iterator.getPreviousItem() + ",");
            iterator.previous();
        }
    }
}

运行结果:

正向遍历:
AA,BB,CC,DD,EE,
反向遍历:
EE,DD,CC,BB,AA,

优点

(1)支持以不同的方式遍历一个聚合对象

(2)简化了聚合类

(3)增加新的聚合类和迭代器类都很方便,无须修改原 有代码,满足“开闭原则”的要求。

缺点

(1)由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭 代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。

(2) 抽象迭代器的设计难度较大,需要充分考虑到系统将来的扩展。

适用场景

(1)访问一个聚合对象的内容而无须暴露它的内部表示。

(2)需要为一个聚合对象提供多种遍历方式。

(3)为遍历不同的聚合结构提供一个统一的接口,在该接口的实现类中为不同的聚合结构提供 不同的遍历方式,而客户端可以一致性地操作该接口。