시냅스

이터레이터 패턴 Java로 구현 본문

디자인 패턴

이터레이터 패턴 Java로 구현

ted k 2022. 8. 17. 15:06

반복자 패턴 Iterator Pattern

  • 객체 요소들의 내부 표현방식을 공개하지 않고, 객체에서 되지 않은, 외부에서 객체에 순회하는 객체를 만든다.
  • 내부에서 객체의 순차적인 제공을 하지 않음
  • 순회 구현 방식이 다르더라도 동일한 방식(메서드)로 순회 할 수 있게 제공
  • 여러 리스트 객체에 대한 동일한 방식으로 순회하는 방법을 제공하기 위해 순회하는 객체를 따로만듬
  • e.g. Java Collection Framework의 Iterator

 

Iterator

  • 요소에 접근하고 순회하는데 필요한 메서드 제공

ConcreteIterator

  • Iterator에 정의된 인터페이스를 구현하는 클래스

Aggregate

  • Iterator 객체를 생성하는 인터페이스 정의
  • 순회할 요소를 가지고 있다.

ConcreteAggregate

  • 해당하는 ConcreteIteratir의 인스턴스를 반환하도록 Iterator 생성 인터페이스를 구현

 

결론

 

  • ConcreteIterator는 리스트를 순회하면서 각 리스트의 요소를 반환하는 메서드도 제공한다.
  • 다양한 순회방법이 제공될 수 있다.
  • 동일한 Aggregate를 구현한 클래스들은 동일한 방식으로 순회할 수 있다.

 

구현

package iterator;

class Constant {
    public static final int FORWARD = 0;
    public static final int REVERSE = 1;
}

abstract class Factory {
    public final Iterator create(Aggregate list, int type) {
        Iterator p = createProduct(list, type);
        return p;
    }

    protected abstract Iterator createProduct(Aggregate list, int type);
}

class IteratorFactory extends Factory {
    public static IteratorFactory iteratorFactory = new IteratorFactory();
    private IteratorFactory() {
    }
    public static IteratorFactory getInstance() {
        return iteratorFactory;
    }
    @Override
    protected Iterator createProduct(Aggregate list, int type) {
        if (type == Constant.FORWARD)
            return new BookShelfIterator(list);
        else
            return new BookShelfReverseIterator(list);
    }
}

interface Iterator {
    public abstract boolean hasNext();
    public abstract Object next();
}

class Book {
    private String name;
    public Book(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}

class BookShelfReverseIterator implements Iterator {

    BookShelf aggregate;
    int idx;

    public BookShelfReverseIterator(Aggregate aggregate) {
        this.aggregate = (BookShelf) aggregate;
        this.idx = aggregate.getLength() - 1;
    }

    @Override
    public boolean hasNext() {
        return idx >= 0;
    }

    @Override
    public Object next() {
        return aggregate.arr[idx--];
    }
}


class BookShelfIterator implements Iterator {

    BookShelf aggregate;
    int idx;

    public BookShelfIterator(Aggregate aggregate) {
        this.aggregate = (BookShelf) aggregate;
        this.idx = 0;
    }

    @Override
    public boolean hasNext() {
        return aggregate.getLength() - idx > 0;
    }

    @Override
    public Object next() {
        return aggregate.arr[idx++];
    }
}

interface Aggregate {
    public abstract Iterator iterator(int type);
    public int getLength();
}

class BookShelf implements Aggregate {
    int size;
    public Book arr[];
    int cnt;
    Factory factory = IteratorFactory.getInstance();

    public BookShelf(int size) {
        this.size = size;
        this.arr = new Book[size];
        this.cnt = 0;
    }

    @Override
    public Iterator iterator(int type) {
        return factory.create(this, type);
    }

    @Override
    public int getLength() {
        return this.cnt;
    }

    public void appendBox(Book book) {
        if (this.cnt >= size)
            return ;
        arr[cnt] = book;
        this.cnt += 1;
    }
}

public class IteratorImpl {
    public static void main(String[] args) {
        BookShelf bookShelf = new BookShelf(3);
        bookShelf.appendBox(new Book("asd1"));
        bookShelf.appendBox(new Book("asd2"));
        bookShelf.appendBox(new Book("asd3"));
        Iterator iterator = bookShelf.iterator(Constant.FORWARD);
        while (iterator.hasNext()) {
            Book next = (Book) iterator.next();
            System.out.println("next.getName() = " + next.getName());
        }
    }
}

 

Comments