banner
jzman

jzman

Coding、思考、自觉。
github

イテレーター設計パターン

PS:どんな素晴らしいことも、当たり前になってしまうと、もはや貴重ではなくなります。

イテレータデザインパターンは、さまざまな要素に順番にアクセスする方法を提供するために使用される一般的なデザインパターンですが、そのオブジェクトの内部表現を公開することはありません。イテレータデザインパターンは、行動型デザインパターンに属します。

  1. 関連概念
  2. 使用シーン
  3. Java 実装
  4. Dart 実装

関連概念#

  • 抽象集約役割:集約オブジェクトに対する追加、削除などの操作を定義し、イテレータを作成するメソッドを定義します;
  • 具体集約役割:抽象集約役割の具体的な実装クラス;
  • 抽象イテレータ役割:イテレータに関連するメソッドを定義します。例えば、hasNext、first、last などのメソッド;
  • 具体イテレータ役割:抽象イテレータ役割の具体的な実装クラス。

使用シーン#

イテレータデザインパターンの使用シーンは以下の通りです:

  1. 定義された特定のデータ構造に対して、遍歴方法を提供するため;
  2. 集約オブジェクトの実装の詳細を隠すためにイテレータデザインパターンを使用することができます;
  3. 複数の集約オブジェクトが共存する場合、イテレータデザインパターンを使用することで、データ構造の違いによる差異を隠すことができます;

Java 実装#

イテレータデザインパターンを簡単に実装し、抽象集約役割を以下のように定義します:

/**
 * 抽象集約役割
 * Created by jzman
 * Powered by 2019/12/22.
 */
interface Aggregate {
    Iterator createIterator();
}

抽象イテレータ役割を以下のように定義します:

/**
 * 抽象イテレータ役割
 * Created by jzman
 * Powered by 2019/12/22.
 */
interface Iterator {
    Object first();
    Object next();
    boolean isDone();
    Object currentItem();
}

具体的な集約役割と具体的なイテレータ役割を以下のように実装します:

/**
 * 具体的な集約役割
 * Created by jzman
 * Powered by 2019/12/22.
 */
class ConcreteAggregate implements Aggregate {
    private List<Object> mList;
    
    public ConcreteAggregate(List<Object> mList) {
        this.mList = mList;
    }
    
    @Override
    public Iterator createIterator() {
        return new ConcreteIterator();
    }

    /**
     * 具体的なイテレータ役割
     */
    private class ConcreteIterator implements Iterator {

        private int mCursor;

        @Override
        public Object first() {
            return mList.get(0);
        }

        @Override
        public Object next() {
            mCursor++;
            if (mCursor < mList.size()) {
                return mList.get(mCursor);
            }
            return null;
        }

        @Override
        public boolean isDone() {
            return mCursor >= mList.size();
        }

        @Override
        public Object currentItem() {
            return mList.get(mCursor);
        }
    }
}

上記のコードをテストします:

/**
 * イテレータテスト
 * Created by jzman
 * Powered by 2019/12/22.
 */
class Client {
    public static void main(String[] args) {
        List<Object> objects = new ArrayList<>();
        objects.add("A");
        objects.add("B");
        objects.add("C");
        ConcreteAggregate aggregate = new ConcreteAggregate(objects);

        // イテレータを取得
        Iterator iterator = aggregate.createIterator();
        // 遍歴
        while (!iterator.isDone()) {
            Object o = iterator.currentItem();
            System.out.println("data:" + o);
            iterator.next();
        }
    }
}

テスト結果は以下の通りです:

data:A
data:B
data:C

Dart 実装#

main(){
  List<Object> mList = ["A","B","C"];
  Aggregate aggregate = new ConcreteAggregate(mList);
  Iterator iterator = aggregate.createIterator();
  while (!iterator.isDone()) {
    Object obj = iterator.currentItem();
    print("data:${obj.toString()}");
    iterator.next();
  }
}

// 抽象イテレータ役割
abstract class Iterator{
  Object first();
  Object next();
  bool isDone();
  Object currentItem();
}

// 具体的なイテレータ役割
class ConcreteIterator implements Iterator{
  int mCursor = 0;
  List<Object> mList;

  ConcreteIterator(this.mList);

  @override
  Object first() {
      return mList[0];
  }

  @override
  Object next() {
      mCursor++;
      if (mCursor < mList.length) {
          return mList[mCursor];
      }
      return null;
  }

  @override
  bool isDone() {
      return mCursor >= mList.length;
  }

  @override
  Object currentItem() {
      return mList[mCursor];
  }
}

// 抽象集約役割
abstract class Aggregate {
  Iterator createIterator();
}

// 具体的な集約役割
class ConcreteAggregate implements Aggregate{
  List<Object> mList;
  ConcreteAggregate(this.mList);
  @override
  Iterator createIterator(){
    return new ConcreteIterator(mList);
  }
}

テスト効果は以下の通りです:

data:A
data:B
data:C

イテレータデザインパターンは、集合を遍歴する際によく使用されますが、使用する際にはデザインパターンの概念がない場合もあります。このような概念は、潜在的に自分のコーディング能力を向上させることができます。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。