大話設計模式筆記(十七)の迭代器模式

迭代器模式

定義

提供一種方法順序訪問一個聚合對象中各個元素,而又不暴露該對象的內部表示。ide

何時用?

  • 當你須要訪問一個彙集對象,並且無論這些對象是什麼都須要遍歷的時候,你就應該考慮用迭代器模式
  • 你須要對彙集有多種方式遍歷時,能夠考慮用迭代器模式。

UML圖

模板代碼

Aggregate

/**
 * 彙集抽象類
 * Created by callmeDevil on 2019/8/17.
 */
public abstract class Aggregate {
    // 建立迭代器
    public abstract Iterator createIterator();
}

Iterator

/**
 * 迭代器抽象類
 * Created by callmeDevil on 2019/8/17.
 */
public abstract class Iterator {
    // 用於定義獲得開始對象、獲得下一對象、判斷是否到結尾、當前對象等抽象方法
    public abstract Object first();
    public abstract Object next();
    public abstract boolean isDone();
    public abstract Object currentItem();
}

ConcreteAggregate

/**
 * 具體彙集類
 * Created by callmeDevil on 2019/8/17.
 */
public class ConcreteAggregate extends Aggregate {

    // 存放聚合對象
    private List<Object> items = new ArrayList();

    @Override
    public Iterator createIterator() {
        return new ConcreteIterator(this);
    }

    // 返回彙集的總個數
    public int count() {
        return items.size();
    }

    // 聲明一個索引器
    public Object get(int index) {
        return items.get(index);
    }
    public boolean set(Object o) {
        return items.add(o);
    }

}

ConcreteIterator

/**
 * 具體迭代器類
 * Created by callmeDevil on 2019/8/17.
 */
public class ConcreteIterator extends Iterator {

    // 定義一個具體彙集對象
    private ConcreteAggregate aggregate;
    private int current = 0;

    public ConcreteIterator(ConcreteAggregate aggregate){
        // 初始化時將具體的彙集對象傳入
        this.aggregate = aggregate;
    }

    @Override
    public Object first() {
        // 獲得彙集的第一個對象
        return aggregate.get(0);
    }

    @Override
    public Object next() {
        Object ret = null;
        current++;
        if (current < aggregate.count()) {
            // 獲得彙集的下一個對象
            ret = aggregate.get(current);
        }
        return ret;
    }

    @Override
    public boolean isDone() {
        // 判斷當前是否遍歷到結尾
        return current >= aggregate.count();
    }

    @Override
    public Object currentItem() {
        // 返回當前的彙集對象
        return aggregate.get(current);
    }

}

測試

public class Test {
    public static void main(String[] args) {
        // 公交車彙集對象
        ConcreteAggregate a = new ConcreteAggregate();
        // 新上來的乘客
        a.set("路飛");
        a.set("鳴人");
        a.set("一護");
        a.set("悟空");
        a.set("納茲");
        a.set("琦玉");
        // 售票員登場,看好上車的是哪些人,即聲明迭代器對象
        Iterator i = new ConcreteIterator(a);
        System.out.println(String.format("車位No.1乘客:%s", i.first()));
        while (!i.isDone()){
            System.out.println(String.format("%s 來不及解釋了,快上車!", i.currentItem()));
            i.next();
        }
    }
}

測試結果

車位No.1乘客:路飛
路飛 來不及解釋了,快上車!
鳴人 來不及解釋了,快上車!
一護 來不及解釋了,快上車!
悟空 來不及解釋了,快上車!
納茲 來不及解釋了,快上車!
琦玉 來不及解釋了,快上車!

倒序遍歷

ConcreteIteratorDesc

/**
 * 倒序具體迭代器
 * Created by callmeDevil on 2019/8/17.
 */
public class ConcreteIteratorDesc extends Iterator{

    // 定義一個具體彙集對象
    private ConcreteAggregate aggregate;
    private int current = 0;

    public ConcreteIteratorDesc(ConcreteAggregate aggregate){
        // 初始化時將具體的彙集對象傳入
        this.aggregate = aggregate;
        current = aggregate.count() - 1;  //不一樣1
    }

    @Override
    public Object first() {
        // 獲得彙集的第一個對象
        return aggregate.get(aggregate.count() - 1); //不一樣2
    }

    @Override
    public Object next() {
        Object ret = null;
        current--;  //不一樣3
        if (current >= 0) {  //不一樣4
            // 獲得彙集的下一個對象
            ret = aggregate.get(current);
        }
        return ret;
    }

    @Override
    public boolean isDone() {
        // 判斷當前是否遍歷到結尾
        return current < 0;  //不一樣5
    }

    @Override
    public Object currentItem() {
        // 返回當前的彙集對象
        return aggregate.get(current);
    }

}

測試

將順序測試類中聲明迭代器具體對象改成倒序的 ConcreteIteratorDesc 便可。測試

測試結果

車位No.1乘客:琦玉
琦玉 來不及解釋了,快上車!
納茲 來不及解釋了,快上車!
悟空 來不及解釋了,快上車!
一護 來不及解釋了,快上車!
鳴人 來不及解釋了,快上車!
路飛 來不及解釋了,快上車!

總結

迭代器模式就是分離了集合對象的遍歷行爲,抽象出一個迭代器類來負責,這樣既能夠作到不暴露集合的內部結構,又能夠讓外部代碼透明的訪問集合內部的數據。this

相關文章
相關標籤/搜索