본문 바로가기
디자인 패턴

6. Iterator Pattern

by spaul 2023. 11. 14.

▣ What is Iterator Pattern?

 Provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation

 

 

Iterator Pattern(반복자 패턴)은 '여러 요소를 담고 있는 객체(배열, 리스트, 맵 등)'의 내부 구조에 대한 이해 없이, 각 요소를 순서대로 접근하고 사용할 수 있는 방법을 제공하는 것입니다.

 

반복자 패턴의 클래스 다이어그램

 

예를 들어 우리가 아래와 같은 코드를 작성했다고 해봅시다.

import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        int[] arr = new int[5];
        ArrayList<Integer> list = new ArrayList<Integer>();

        for(int i = 0; i < 5; i++) {
            list.add(i, i+10);
        }

        for (int i = 0; i < arr.length; i++) {
            arr[i] = i - 10;
        }

        System.out.println("Elements of List");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

        System.out.println("Elements of Array");
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

 

실행 결과

 

 배열과 ArrayList를 각각 하나씩 생성한 뒤 원소를 할당하고, 자료 구조를 순회하며 하나씩 출력하는 간단한 코드입니다. 코드를 보면 아시겠지만, ArrayList와 배열을 순회하는 코드 모두 동일한 구조를 가집니다. 인덱스 i를 통해 i번째에 위치한 element를 출력하는 것이지요. 위 코드는 아래와 같이 바꿀 수 있습니다. 

 

import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        int[] arr = new int[5];
        ArrayList<Integer> list = new ArrayList<Integer>();

        for(int i = 0; i < 5; i++) {
            list.add(i, i+10);
        }

        for (int i = 0; i < arr.length; i++) {
            arr[i] = i - 10;
        }

        System.out.println("Elements of List");
        for(int l : list) {
            System.out.println(l);
        }

        System.out.println("Elements of Array");
        for (int a : arr) {
            System.out.println(a);
        }
    }
}

 

 출력 결과는 동일합니다. 첫 번째 코드에서는 for-loop의 조건문으로 i < list.size()와 사용했고 i < arr.length를 각각 사용했지만 두 번째 코드에서는 list 객체 또는 arr 객체의 원소를 각각 l과 a에 하나씩 대입하여 출력하였습니다(이러한 방식을 for-each라고 합니다). 참고로 ArrayList의 elements는 Integer 클래스 형태로 저장되어있지만 출력할 때는 자동으로 int 자료형으로 unboxing되기 때문에 정상적으로 출력됩니다.

 

 이제 처음에 설명했던 반복자 패턴의 정의가 조금 이해가 되실까요? 컬렉션 객체의 구조는 배열과 ArrayList로 각각 다르지만, for-each를 사용하여 객체에 접근하는 방식이 같아진 것을 볼 수 있습니다. 그리고 for-each는 요소를 삭제 또는 변경하는 작업에서는 사용할 수 없기 때문에, 요소를 삭제 또는 변경해야 한다면 일반적인 while이나 for문을 사용해야 합니다.

 

 그렇다면 반복자 패턴은 자바에 기본으로 구현되어 있는 배열이나 ArrayList와 같은 컬렉션에만 사용 가능할까요? 정답은 '아닙니다'입니다. 사용자가 제작한 컬렉션 클래스에서도, 아래 3가지 조건을 만족하기만 한다면 iterator패턴을 사용할 수 있습니다.

 

● iterator() : 반복자에 대한 참조(Iterator 자료형)를 반환

● hasNext() : 요소가 더 존재하는지 확인하여 true 또는 false 반환

● next() : 다음 요소를 가져와 반환(Object 클래스를 반환하므로 변환해서 사용해야함)

 

https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html

위의 오라클 공식 문서를 들어가서 살펴보시면 더 자세히 보실 수 있습니다.

 

References

[1] 조용주, 고급객체지향프로그래밍

[2] Eric Freeman, Head Frist Design Patterns

 

'디자인 패턴' 카테고리의 다른 글

8. Factory Method Pattern, Abstract Factory Patter  (0) 2023.12.02
7. Decorator Pattern  (0) 2023.11.28
5. Singleton Pattern  (0) 2023.11.13
4. Observer Pattern  (0) 2023.11.07
3. Strategy Pattern  (0) 2023.10.29