【行为型模式七】迭代器模式

一、封装自定义数据结构的访问方式

通常我们可能会自定义一种数据结构,例如数组实现的栈,需要提供一个访问该栈中各个元素的方法,又不想暴露该栈是用数组实现的还是链表实现的。就可以使用迭代器模式。通常每种语言中都内置了迭代器模式,例如Java中的Iterable接口,就是为迭代器模式准备的。所有能使用foreach方式遍历的容器(所有Collection的子类)都实现了Iterable接口。

二、迭代器模式

迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示,其别名为游标(Cursor)。迭代器模式是一种对象行为型模式。

迭代器模式就是分离了集合变量的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。

2.1 迭代器模式的角色

使用迭代器模式实现数组栈遍历的类图:
迭代器模式

  • Iterator(抽象迭代器):它定义了访问和遍历元素的接口,声明了用于遍历数据元素的方法,例如:用于获取第一个元素的first()方法,用于访问下一个元素的next()方法,用于判断是否还有下一个元素的hasNext()方法,用于获取当前元素的currentItem()方法等,在具体迭代器中将实现这些方法。

  • ConcreteIterator(具体迭代器):它实现了抽象迭代器接口,完成对聚合对象的遍历,同时在具体迭代器中通过游标来记录在聚合对象中所处的当前位置,在具体实现时,游标通常是一个表示位置的非负整数。

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

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

三、使用迭代器模式实现数组栈遍历

3.1 抽象迭代器类

public abstract class Iterator {
    public abstract boolean hasNext();
    public abstract Object first() throws Exception;
    public abstract Object next() throws Exception;
}

3.2 具体迭代器类

此类实现从栈顶到栈底遍历。

public class ConcreteIterator extends Iterator {
    private ConcreteAggregate concreteAggregate;
    private int cursor;
    public ConcreteIterator(ConcreteAggregate concreteAggregate) {
        this.concreteAggregate = concreteAggregate;
        cursor = concreteAggregate.getSize();
    }
    @Override
    public boolean hasNext() {
        return cursor > 0;
    }

    @Override
    public Object first() throws Exception {
        cursor = concreteAggregate.getSize() - 1;
        return concreteAggregate.current(cursor);
    }

    @Override
    public Object next() throws Exception {
        return concreteAggregate.current(--cursor);
    }
}

3.3 抽象聚集类

只有一个创建迭代器的方法

public abstract class Aggregate {
    public abstract Iterator createIterator();
}

3.4 具体聚集类

实现一个数组栈。

public class ConcreteAggregate extends Aggregate{
    private Integer[] intStack;
    private int capacity;
    private int size = 0;

    public int getCapacity() {
        return capacity;
    }

    public int getSize() {
        return size;
    }

    public ConcreteAggregate(int capacity) {
        this.capacity = capacity;
        intStack = new Integer[capacity];
    }
    @Override
    public Iterator createIterator() {
        return new ConcreteIterator(this);
    }
    public void push(int num) throws Exception {
        if (size < capacity) {
            intStack[size++] = num;
        }else {
            throw new Exception("栈已满!");
        }
    }
    public int pop() throws Exception {
        if (size > 0) {
            return intStack[--size];
        }else {
            throw new Exception("栈已空!");
        }
    }
    public int current(int index) throws Exception {
        if (size > 0 && index < size) {
            return intStack[index];
        }else if (size == 0){
            throw new Exception("栈为空!");
        }else {
            throw new Exception("索引越界!");
        }
    }
}

3.5 客户端

public class Client {
    /**
     * 使用迭代器模式遍历数组栈
     */
    public static void showByIterator() throws Exception {
        ConcreteAggregate intStack = new ConcreteAggregate(5);
        for (int i = 0; i < intStack.getCapacity(); i++) {
            intStack.push(i);
        }
        Iterator stackIterator = intStack.createIterator();
        while (stackIterator.hasNext()) {
            System.out.println(stackIterator.next());
        }
    }

    public static void main(String[] args) {
        try {
            showByIterator();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 运行结果
4
3
2
1
0

实现从栈顶到栈底遍历了该栈。

四、迭代器模式总结

在迭代器模式中,提供了一个外部的迭代器来对聚合对象进行访问和遍历,迭代器定义了一个访问该聚合元素的接口,并且可以跟踪当前遍历的元素,了解哪些元素已经遍历过而哪些没有。迭代器的引入,将使得对一个复杂聚合对象的操作变得简单。

在迭代器模式中应用了工厂方法模式,抽象迭代器对应于抽象产品角色,具体迭代器对应于具体产品角色,抽象聚合类对应于抽象工厂角色,具体聚合类对应于具体工厂角色。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值