반복자 패턴

정선호·2023년 5월 25일
0

Design Patterns

목록 보기
20/24

반복자 패턴

위키피디아 - 반복자 패턴
설명 및 스도코드

  • 컬렉션의 요소들의 기본 표현을 노출하지 않고 그들을 하나씩 순화할 수 있도록 해주는 패턴
    • 다시말해 aggregate 유형에 무관한 동일 순차 접근 방법을 제공하는 것이며, 여기서 aggregate란 반복자객체를 생성하기위한 인터페이스를 정의하는 것이고 iterator 란 요소에 접근 할 수 있고 순회 할 수 있는 인터페이스를 정의하는 것이다.
    • 이는 컨테이너로부터 알고리즘을 분리시킨다. 일부 알고리즘의 경우 컨테이너에 특화되어 있기 때문에 분리가 불가능하다

반복자 패턴의 구조

  • 반복자(Iterator) 인터페이스
    • 컬렉션의 순회에 필요한 작업들(다음 요소 가져오기, 현재 위치 가져오기, 반복자 다시 시작 등)을 선언
  • 구상 반복자(Concrete Iterator)
    • 컬렉션 순회를 위한 특정 알고리즘 구현
    • 반복자 객체는 순회의 진행 상황을 자체적으로 추적해야 한다
    • 이는 여러 반복자들이 같은 컬렉션을 서로 독립적으로 순회할 수 있도록 한다
  • 컬렉션(Iterable Collection) 인터페이스
    • 컬렉션과 호환되는 반복자들을 가져오기 위한 하나 이상의 메서드들 선언
    • 메서드들의 반환 유형은 반복자 인터페이스의 유형으로 선언되어야 한다. 그래야 구상 컬렉션들이 다양한 유형의 반복자들을 반환할 수 있기 때문
  • 구상 컬렉션(Concrete Collection)
    • 클라이언트가 요청할 때마다 특정 구상 반복자 클래스의 새 인스턴스 반환
    • 컬렉션의 나머지 코드는 같은 클래스에 있으나 세부사항들은 실제 패턴에 크게 중요하지 않음
  • 클라이언트(Client)
    • 반복자들과 컬렉션들의 인터페이스를 통해 둘을 같이 작동시켜 같은 클라이언트 코드로 다양한 컬렉션들과 반복자들을 사용할 수 있다
    • 일반적으로 클라이언트들은 자체적으로 반복자들을 생성하지 않고 대신 컬렉션들이 가져옴. 그러나 특수한 경우에는 클라이언트가 반복자를 직접 만들 수 있음

반복자 패턴의 적용

  • 컬랙션이 내부에 복잡한 데이터 구조가 있지만, 이 구조의 복잡성을 보안이나 편의상의 이유로 클라이언트들로부터 숨기고 싶을 때
  • 반복자 패턴을 사용해서 앱 전체에서 순회 코드의 중복을 줄이고 싶을 때
  • 코드가 다른 데이터 구조들을 순회할 수 있기를 원할 때 또는 이러한 구조들의 유형을 미리 알 수 없을 때

다른 패턴과의 관계

  • 반복자를 사용해 복합체 패턴 트리들을 순회할 수 있다
  • 팩토리 메서드를 반복자와 함께 사용하여 컬렉션 자식 클래스들이 해당 컬렉션들과 호환되는 다양한 유형의 반복자들을 반환하도록 할 수 있다
  • 메멘토 패턴을 반복자 패턴과 함께 사용하여 현재 순회 상태를 포착하고 필요한 경우 롤백할 수 있다
  • 비지터 패턴과 반복자 패턴을 함께 사용해 복잡한 데이터 구조를 순회하여 해당 구조의 요소들의 클래스들이 모두 다르더라도 이러한 요소들에 대해 어떤 작업을 실행할 수 있다

반복자 패턴의 예제

  • 반복자 인터페이스
public interface Iterator {
    public abstract boolean hasNext();
    public abstract Object next();
}
  • 구상 반복자
public class StudyGroupIterator implements Iterator {
    private Study_Group study_group;
    private int index;
    
    public StudyGroupIterator(Study_Group study_group)
    {
        this.study_group =study_group;
        this.index = 0;
    }
    
    public  boolean hasNext()
    {
        if(index < study_group.getLength())
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    public Object next()
    {
        Student student = study_group.getStudent(index);
        index++;
        return student;
    }
}
  • 컬렉션 인터페이스
public interface Aggregate {
    public abstract Iterator iterator();
}
  • 구상 컬렉션
// 컬렉션의 요소
public class Student {
    private String name="";
    private int age ;
    
    public Student(String name, int age)
    {
        this.name=name;
        this.age =age;
    }
    public String getName()
    {
        return name;
    }
    public int getAge()
    {
        return age;
    }
}

// 구상 컬렉션
public class Study_Group implements Aggregate{
    
    private Student[] Students;
    private int num =0;
    
    public Study_Group(int num)
    {
        this.Students = new Student[num];
    }
    public Student getStudent(int index)
    {
        return Students[index];
    }
    public void AddStudnet(Student student)
    {
        this.Students[num] = student;
        num++;
    }
    public int getLength()
    {
        return num;
    }
    
    public StudyGroupIterator iterator()
    {
        return new StudyGroupIterator(this);
    }
}
  • 클라이언트
public class Main {
    
    public static void main(String argsp[])
    {
        Study_Group study_group = new Study_Group(5);
        study_group.AddStudnet(new Student("이기택",27));
        study_group.AddStudnet(new Student("최민수",27));
        study_group.AddStudnet(new Student("원빈",27));
        study_group.AddStudnet(new Student("홍길동",27));
        study_group.AddStudnet(new Student("나비",27));
        
        StudyGroupIterator iterator = study_group.iterator();
        
        while(iterator.hasNext())
        {
            Student student = (Student)iterator.next();
            System.out.println("이름:" + student.getName());
            System.out.println("나이:" + student.getAge());
            System.out.println("------------------");
        }
    }
}
profile
학습한 내용을 빠르게 다시 찾기 위한 저장소

0개의 댓글