<용어 정의>
- 집합체 : 특정 객체들을 자료구조에 모아두고 로직을 처리하는 객체
- 항목 : 집합체 내 자료구조에 저장되는 객체
(여러명의 학생들이 A수업을 수강할 때, A수업 객체가 집합체, 학생 객체가 항목에 해당한다.)
⇒ 집합체 본연의 기능
과 순회 기능
을 분리하는 것 → SRP(단일 책임 원칙)
⇒ 해당 집합체의 사용자(클라이언트)에게 집합체 구현 내용을 노출시키지 않아도 잘 동작될 수 있도록 설계하는 것 → 캡슐화
⇒ 이로써 사용자는 집합체 내부에서 항목들이 어떤 자료구조(Array, List, Set, …)로 구현되어 있는지 몰라도 각 항목에 접근하여 특정 동작을 수행할 수 있다.
사진1. Iterator 패턴 구조
createIterator()
)를 포함하고 있다.createIterator()
메서드를 재정의한다.public class Student {
private String name;
public Student(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
public class Lecture{
private Student[] students;
private int numOfStudents;
public Lecture(int maxOfStudents) {
this.students = new Student[maxOfStudents];
}
public Student getStudent(int index) {
return students[index];
}
public void addStudent(Student student) {
students[numOfStudents] = student;
numOfStudents += 1;
}
public int getNumOfStudents() {
return numOfStudents;
}
}
사진1에서 다룬 구조를 그대로 적용해 보면, 다음과 같은 인터페이스가 필요하다.
먼저 Iterator 인터페이스와 구현체를 구현해보자.
Iterator 인터페이스는 다음과 같이 구현될 수 있다.
public interface Iterator {
boolean hasNext();
Object next();
}
Lecture
클래스에 맞추어 구현하면 다음과 같이 구현될 수 있다. : LectureIterator
public class LectureIterator implements Iterator {
private Lecture lecture;
private int index;
public LectureIterator(Lecture lecture) {
this.lecture = lecture;
this.index = 0;
}
@Override
public boolean hasNext() {
if (index < lecture.getNumOfStudents())
return true;
return false;
}
@Override
public Object next() {
return lecture.getStudent(index++);
}
}
public interface Aggregate {
Iterator createIterator();
}
Lecture
클래스에서 구현하면 다음과 같이 구현될 수 있다.public class Lecture implements Aggregate {
private Student[] students;
private int numOfStudents;
public Lecture(int maxOfStudents) {
this.students = new Student[maxOfStudents];
}
public Student getStudent(int index) {
return students[index];
}
public void addStudent(Student student) {
students[numOfStudents] = student;
numOfStudents += 1;
}
public int getNumOfStudents() {
return numOfStudents;
}
@Override
public Iterator createIterator() {
return new LectureIterator(this);
}
}
Lecture lecture = new Lecture(5);
lecture.addStudent(new Student("student1"));
lecture.addStudent(new Student("student2"));
lecture.addStudent(new Student("student3"));
lecture.addStudent(new Student("student4"));
lecture.addStudent(new Student("student5"));
Iterator lectureIterator = lecture.createIterator();
Student student;
while (lectureIterator.hasNext()) {
student = (Student)lectureIterator.next();
System.out.println(student.getName());
}
//student1
//student2
//student3
//student4
//student5
Lecture
) 내에서 항목(Student
)들이 어떤식으로 저장되어 있는지 모르지만, Iterator를 통해 각 항목들에 접근하여 특정 동작을 수행할 수 있다.장점
사용자(Client)는 집합체가 어떻게 구현되어 있는지 알 필요도 없고 알 수도 없다. 하지만 각 항목들을 순회하는 동작을 수행할 수 있다.
→ 캡슐화
순회 관련 로직을 Iterator로 분리함으로써 집합체는 이를 다루지 않아도 된다. 즉, 집합체 본연의 로직과 순회 관련 로직을 분리한 것이다.
→ SRP
Iterator 인터페이스를 둠으로써 여러 형태의 집합체에 적용할 수 있다. → 다형성
단점
참고 자료