# 이터레이터(Iterator) 패턴

# 이터레이터 패턴이란 무엇인가요?

이터레이터 패턴은 이터레이터를 사용하여 컬렉션(객체의 모음)의 요소들에 접근하는 디자인 패턴입니다. 이를 통해 순회할 수 있는 여러가지 자료형의 구조와는 상관없이 이터레이터라는 하나의 인터페이스로 순회가 가능합니다.
정리하자면, 자료구조에 상관없이 객체 접근 방식을 통일시키는 패턴입니다.

  • UML
    이터레이터uml
    • Iterator : 집합체의 요소들을 순서대로 검색하기 위한 인터페이스 정의
    • ConcreateIterator : Iterator 인터페이스를 구현한 것
    • Aggregate : 여러 요소들로 이루어져 있는 집합체
    • ConcreateAggregate : Aggreagate 인터페이스를 구현하는 클래스

# 예시 코드

길드에 있는 캐릭터들의 정보를 Iterator 패턴을 적용하여 순차적으로 검색하는 예제

  • Aggregate 인터페이스
public interface Aggregate {
    public abstract Iterator iterator();    
}
  • Iterator 인터페이스
public interface Iterator {
    public abstract boolean hasNext();  //접근 할 데이터가 있는지 판단하는 메소드
    public abstract Object next();  // 해당 인덱스의 객체를 반환 받는 메소드
}
  • Aggregate의 구현체인 Guild와 해당 클래스가 갖는 Character 객체
public class Character {
    private String nickname="";
    private int level;
    
    public Character(String nickname, int level) { 
        this.nickname = nickname;
        this.level = level;
    }
    
    getter...
}

public class Guild implements Aggregate {
    private Character[] Characters;
    private int num = 0;

    public Guild(int num) {
        this.Characters = new Character[num];
    }

    public Character getCharacter(int index) {
        return Characters[index];
    }
    
    public void addCharacter(Character character) {
        this.Characters[num] = character;
        num++;
    }

    public int getLength()
    {
        return num;
    }
    
    @Override
    public GuildIterator iterator() {
        return new GuildIterator(this);
    }
}
  • GuildIterator
public class GuildIterator implements Iterator {
    private Guild guild;
    private int index;
    
    public GuildIterator(Guild guild)
    {
        this.guild = guild;
        this.index = 0;
    }
    
    @Override
    public  boolean hasNext()
    {
        if(index < guild.getLength())
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    
    @Override
    public Object next()
    {
        Character character = Guild.getCharacter(index);
        index++;
        return character;
    }
}
  • 사용
public class Main {
    public static void main(String args[])
    {
        Guild guild = new Guild(3);
        guild.addCharacter(new Character("얼음법사", 140));
        guild.addCharacter(new Character("불꽃전사", 200));
        guild.addCharacter(new Character("초록궁수", 160));
        
        GuildIterator iterator = guild.iterator();
        
        while(iterator.hasNext())
        {
            Character character = (Character) iterator.next();
            System.out.println("닉네임:" + character.getNickName());
            System.out.println("레벨:" + character.getLevel());
        }
    }
}

# 이터레이터 패턴의 장점은 무엇인가요?

  • 집합체 클래스의 응집도를 높여줍니다. (집합을 가진 객체와 원소를 탐색하는 영역이 분리 되어 있음)
  • 집합체 내에서 어떤 식으로 일이 처리되는지 알 필요 없이, Iterator만 알고있으면 집합체 안에 들어있는 모든 항목에 접근 할 수 있게 해줍니다.

# 이터레이터 패턴의 단점은 무엇인가요?

  • 사용자가 직접 반복자를 삭제하는 책임을 가져야합니다.
  • 순회 알고리즘 구현 부분에 따라서 캡슐화 전략을 위배할 수 도 있습니다.

# 참고자료

출처: 주홍철.면접을 위한 CS 전공지식 노트.서울:길벗,2022.
출처: https://lktprogrammer.tistory.com/40 [맛있는 프로그래머의 일상]