ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Iterator Pattern(반복자 패턴)
    STUDY/디자인패턴 2025. 2. 2. 19:44

    반복자 패턴이란?

    컬렉션의 요소들의 기본 표현(리스트, 스택, 트리 등)을 노출하지 않고 그들을 하나씩 순회할 수 있도록 하는 행동 디자인 패턴

     

     

    반복자 패턴은 컬렉션의 순회 동작을 반복자라는 별도의 객체로 추출한다. 반복자 객체는 알고리즘 자체를 구현하는 것 외에도 모든 순회 세부 정보들(현재 위치 및 남은 요소들의 수 등)을 캡슐화하기 때문에 여러 반복자들은 서로 독립적으로 동시에 같은 컬렉션을 통과할 수 있다. 

     

    일반적으로 반복자들은 컬렉션의 요소들을 가져오기 위한 하나의 주 메서드를 제공하고, 클라이언트는 이 메서드를 더 이상 아무것도 반환하지 않을 때까지 계속 실행할 수 있다.

     

    구조

    • Iterator

    컬렉션의 순회에 필요한 작업들을 선언한 반복자 인터페이스

     

    • ConcreteIterator

    컬렉션 순회를 위한 특정 알고리즘들을 구현한 구상 클래스로, 반복자 객체는 순회의 진행 상황을 자체적으로 추적해야 한다. 이는 여러 반복자들이 같은 컬렉션을 서로 독립적으로 순회할 수 있도록 한다.

     

    • IterableCollection

    컬렉션과 호환되는 반복자들을 가져오기 위한 하나 이상의 메서드들을 선언한 컬렉션 인터페이스

     

    • ConcreteCollection

    클라이언트가 요청할 때마다 특정 구상 반복자 클래스의 새 인스턴스들을 반환하는 구상 클래스

     

    예시

    Iterator

    모든 반복자에 대한 공통 인터페이스

    public interface Iterator {
        boolean hasNext();
    
        String getNext();
    }

     

    ConcreteIterator

    반복자는 순회하는 컬렉션에 대한 참조를 가지며, 다른 반복자들과 별도로 컬렉션을 순회하기 때문에 반복자 상태를 저장해야 한다.

    public class ConcreteIterator implements Iterator {
        List<String> list;
        private int nextIndex = 0;
    
        public ConcreteIterator(List<String> list) {
            this.list = list;
        }
    
        @Override
        public boolean hasNext() {
            return nextIndex < list.length;
        }
    
        @Override
        public String next() {
            return list.get(nextIndex++);
        }
    }

     

    IterableCollection

    반복자들을 생성하기 위한 메서드를 선언한다.

    public interface IterableCollection {
         Iterator createIterator();
    }

     

    ConcreteCollection

    public class ConcreteCollection implements IterableCollection {
        List<String> list;
    
        public ConcreteCollection() {
            this.list = new ArrayList<>();
        }
    
        public void add(String text) {
            list.add(text);
        }
    
        @Override
        public Iterator createIterator() {
            return new ConcreteIterator(list);
        }
    }

     

     

    Client

    public class Client {
        ConcreteCollection collection = new ConcreteCollection();
        collection.add("a");
        collection.add("b");
        collection.add("c");
        collection.add("d");
        collection.add("e");
    
        Iterator iterator = collection.createIterator();
    
        while(iterator.hasNext()) {
            System.out.printf("%s -> ", iterator.next());
        }
    }

     

    적용

    1. 컬렉션 내부의 복잡한 데이터 구조를 보안이나 편의상의 이유로 클라이언트로부터 숨기는 경우
    2. 순회 코드의 중복을 줄여야 하는 경우
    3. 코드가 다른 데이터 구조들을 순회할 수 있기를 원하거나 또는 이러한 구조들의 유형을 미리 알 수 없는 경우

     

    장단점

    장점

    • 단일 책임 원칙. 순회 알고리즘들을 별도의 클래스들로 추출하여 클라이언트 코드와 컬렉션들을 정돈할 수 있다.
    • 개방/폐쇄 원칙. 새로운 유형의 컬렉션들과 반복자들을 구현할 수 있으며 이들을 수정없이 기존 코드에 전달할 수 있다.
    • 반복자 객체에는 자신의 고유한 순회 상태가 포함되어 있어서, 같은 컬렉션을 병렬로 순회할 수 있고, 순회를 지연하고 필요할 때 계속할 수 있다.

     

    단점

    • 단순한 컬렉션들과만 작동하는 경우 반복자 패턴을 적용하는 것은 과도할 수 있다.
    • 반복자를 사용하는 것은 일부 특수 컬렉션들의 요소들을 직접 탐색하는 것보다 덜 효과적일 수 있다.

     

Designed by Tistory.