1. 개요
- 반복자 디자인 패턴 (Iterator Design Pattern)은 컬렉션(Collection) 객체의 내부 구조에 상관없이 요소(element)들을 순차적으로 접근하고 싶을 때 사용되는 패턴이다.
2. 조건
- 요소들을 반복적으로 탐색하고자 할 때
- 컬렉션 객체의 내부 구조에 대한 세부 정보를 노출시키지 않고자 할 때
3. 다이어그램
3.1. 설명
Iterator
- 요소에 순차적 접근을 허용하는 인터페이스를 정의한다.
- 다음 요소를 반환하는
next()
메소드가 있다. - 다음 요소의 존재 여부를 확인하는
hasNext()
메소드가 있다.
ConcreteIterator
Iterator
인터페이스의 구현 클래스이다.- 컬렉션 객체의 내부 구조에 맞추어 요소들을 반복하고 관리한다.
Aggregate
Iterator
를 생성하는 인터페이스를 정의한다.- 주로 컬렉션 객체를 표현하며,
iterator()
메소드를 통해 해당 컬렉션 객체에 대한 Iterator를 생성한다.
ConcreteAggregate
Aggregate
인터페이스의 구현 클래스이다.- 실제 요소들을 저장하고,
iterator()
메소드를 구현한다.
4. 구현
public interface Iterator<T> {
boolean hasNext();
T next();
}
public class ConcreteIterator<T> implements Iterator<T> {
private List<T> elements;
private int position;
public ConcreteIterator(List<T> elements) {
this.elements = elements;
this.position = 0;
}
@Override
public boolean hasNext() {
return position < elements.size();
}
@Override
public T next() {
if (hasNext()) return elements.get(position++);
throw new IndexOutOfBoundsException("No more elements");
}
}
public interface Aggregate<T> { Iterator<T> iterator(); }
public class ConcreteAggregate<T> implements Aggregate<T> {
private List<T> elements;
public ConcreteAggregate() {
this.elements = new ArrayList<>();
}
public void add(T element) {
elements.add(element);
}
@Override
public Iterator<T> iterator() {
return new ConcreteIterator<>(elements);
}
}
public class Client {
public static void main(String[] args) {
ConcreteAggregate<String> aggregate = new ConcreteAggregate<>();
aggregate.add("Element 1");
aggregate.add("Element 2");
aggregate.add("Element 3");
Iterator<String> iterator = aggregate.iterator();
while (iterator.hasNext()) {
String element = iterator.next();
System.out.println(element);
}
}
}
출력결과
Element 1
Element 2
Element 3
5. 예시
public interface Iterator<T> {
boolean hasNext();
T next();
}
public class StudentIterator implements Iterator<Student> {
private List<Student> elements;
private int position;
public StudentIterator(List<Student> elements) {
this.elements = elements;
this.position = 0;
}
@Override
public boolean hasNext() {
return position < elements.size();
}
@Override
public Student next() {
if (hasNext()) return elements.get(position++);
throw new IndexOutOfBoundsException("No more elements");
}
}
public interface Aggregate {
Iterator iterator();
}
public class StudentArray implements Aggregate {
private List<Student> students;
public StudentArray() {
students = new ArrayList<>();
}
public void add(Student student) {
students.add(student);
}
@Override
public StudentIterator iterator() {
return new StudentIterator(students);
}
}
public class Client {
public static void main(String[] args) {
StudentArray attendance = new StudentArray();
attendance.add(new Student(0, "James"));
attendance.add(new Student(1, "Jane"));
attendance.add(new Student(2, "John"));
StudentIterator iterator = attendance.iterator();
while (iterator.hasNext()) {
Student student = iterator.next();
System.out.println(student);
}
}
}
출력결과
id: 0, name: James
id: 1, name: Jane
id: 2, name: John
6. 장단점
6.1. 장점
- 클라이언트와 컬렉션 객체를 분리하여 구현할 수 있다.
- 서로 다른 종류의 컬렉션 객체를 동일한 방식으로 접근할 수 있다.
- 컬렉션 객체의 내부 구조를 노출하지 않아 데이터의 무결성과 보안을 보장할 수 있다.
6.2. 단점
- 컬렉션 순회 중 요소를 수정할 수 없다.
- 코드의 복잡성이 증가한다.
- 요소들의 역순이나 임의의 순서의 접근이 제한된다.
관련 포스팅
728x90
'Develop > Design Pattern' 카테고리의 다른 글
[Design Pattern] 데코레이터 (Decorator) 패턴 (0) | 2024.06.19 |
---|---|
[Design Pattern] 싱글톤 (Singleton) 패턴 (0) | 2023.12.25 |
[Design Pattern] 추상 팩토리 (Abstract Factory) 패턴 (0) | 2023.12.21 |
[Design Pattern] 팩토리 메소드 (Factory Method) 패턴 (0) | 2023.12.20 |
[Design Pattern] 팩토리 (Factory) 패턴 (0) | 2023.12.20 |