横たわるデザインパターンのノート(XVII)のイテレータパターン

イテレータパターン

定義

オブジェクト表現の内部を露出させることなく、各集合オブジェクト要素のシーケンシャルアクセスを提供する方法。

ときに使用するには?

  • あなたは関係なく、これらのオブジェクトをトラバースするのに必要なものを集計オブジェクトにアクセスしない、とする必要があるときは、反復モードを使用することを検討すべきです
  • あなたが行き来するためのさまざまな方法を収集する必要がある場合には、反復モードを使用することを検討してください。

UMLダイアグラム

テンプレートのコード

集計

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

イテレータ

/**
 * 迭代器抽象类
 * 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乘客:琦玉
琦玉 来不及解释了,快上车!
纳兹 来不及解释了,快上车!
悟空 来不及解释了,快上车!
一护 来不及解释了,快上车!
鸣人 来不及解释了,快上车!
路飞 来不及解释了,快上车!

概要

イテレータパターンは、両方のコレクションの内部構造を露出することなく行うことができるように、関与することがオブジェクトのトラバーサル挙動収集、抽象イテレータクラスの分離であるだけでなく、内部データの外部のコード・セットへの透過的なアクセスを可能にします。

おすすめ

転載: www.cnblogs.com/call-me-devil/p/11368582.html