반복자 패턴
위키피디아 - 반복자 패턴
설명 및 스도코드
- 컬렉션의 요소들의 기본 표현을 노출하지 않고 그들을 하나씩 순화할 수 있도록 해주는 패턴
- 다시말해 aggregate 유형에 무관한 동일 순차 접근 방법을 제공하는 것이며, 여기서 aggregate란 반복자객체를 생성하기위한 인터페이스를 정의하는 것이고 iterator 란 요소에 접근 할 수 있고 순회 할 수 있는 인터페이스를 정의하는 것이다.
- 이는 컨테이너로부터 알고리즘을 분리시킨다. 일부 알고리즘의 경우 컨테이너에 특화되어 있기 때문에 분리가 불가능하다
반복자 패턴의 구조
![](https://velog.velcdn.com/images/_hoya_/post/79dcbd58-164e-4a21-9343-dbd781823341/image.png)
- 반복자(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("------------------");
}
}
}