디자인패턴
[Java][디자인 패턴] 14. 반복자 패턴 (Iterator Pattern)
반복자 패턴은 내부 구조를 노출하지 않고 집합체를 통해 원소 객체에 순차적으로 접근할 수 있는 방법을 제공한다.
반복자 패턴이란?
- 반복자 패턴은 순한 알고리즘이 실제 구현된 객체에 의존하지 않고, 독립적인 동작을 유지하기 위해 객체의 내부 메서드에 직접 접근하지 않는다. 대신 반복자의 메서드를 호출하여 처리한다.
반복자 패턴 구조
- Iterator
- 집합체의 요소들을 순서대로 검색하기 위한 인터페이스
- ConcreateIterator
- Iterator 인터페이스 구현
- Aggregate
- 여러 요소들로 이루어져 있는 집합체
- ConcreateAggregate
- Aggreagate 인터페이스를 구현하는 클래스
반복자 패턴 예시 코드 구조
팀에는 여러 Worker가 있다. 이런 상황에서 팀원들에게 공통적인 행동을 반복적으로 수행할 수 있게 Iterator를 제공한다.
(일반적인 상황에서는 Worker를 배열이 아니라 이미 Iterator를 구현하고 있는 Collection을 사용할 것 같지만(List 등), 예제를 위해 배열로 선언하고 예제 코드를 짜보았다.)
반복자 패턴 코드
1. WorkerType enum 클래스
public enum WorkerType {
DEVELOPER("DEVELOPER", "개발자"),
MANAGER("MANAGER", "매니저"),
QA("QA", "QA"),
PLANNER("PLANNER", "기획자");
private final String code;
private final String value;
WorkerType(String code, String value) {
this.code = code;
this.value = value;
}
public String getCode() {
return code;
}
public String getValue() {
return value;
}
}
2. Worker 클래스
public class Worker {
private final String name;
private final WorkerType type;
public Worker(String name, WorkerType type) {
this.name = name;
this.type = type;
}
public String getName() {
return name;
}
public WorkerType getType() {
return type;
}
}
3. Aggregate 인터페이스
import java.util.Iterator;
public interface Aggregate<T> {
Iterator<T> iterator();
}
4. Aggregate를 구현하는 Team 클래스
Worker 배열을 들고 있으며, Worker를 순회할 수 있는 메서드를 iterator를 제공한다.
public class Team implements Aggregate<Worker> {
private final Worker[] workers;
private final String name;
private int lastIndex = 0;
public Team(String name, int size) {
this.name = name;
workers = new Worker[size];
}
public void addTeamMember(Worker worker) {
if (lastIndex < workers.length) {
this.workers[lastIndex] = worker;
lastIndex++;
} else {
System.out.println("팀의 정원이 꽉 찼습니다.");
}
}
public Worker getWorker(int index) {
return workers[index];
}
public int getSize() {
return workers.length;
}
public String getName() {
return name;
}
@Override
public Iterator<Worker> iterator() {
return new TeamIterator(this);
}
}
5. Team을 순회할 수 있는 기능을 제공하는 TeamIterator 클래스
public class TeamIterator implements Iterator<Worker> {
private final Team team;
private int index;
public TeamIterator(Team team) {
this.team = team;
this.index = 0;
}
@Override
public boolean hasNext() {
return index < team.getSize();
}
@Override
public Worker next() {
Worker worker = team.getWorker(index);
index++;
return worker;
}
}
6. Team을 순회하는 반복자 패턴 테스트 코드
class TeamTest {
@Test
@DisplayName("팀 반복 테스트")
void teamTest() {
Team team = new Team("TF팀", 5);
team.addTeamMember(new Worker("이모씨", WorkerType.MANAGER));
team.addTeamMember(new Worker("김모씨", WorkerType.DEVELOPER));
team.addTeamMember(new Worker("송모씨", WorkerType.DEVELOPER));
team.addTeamMember(new Worker("임모씨", WorkerType.PLANNER));
team.addTeamMember(new Worker("장모씨", WorkerType.QA));
System.out.println("팀 이름: " + team.getName());
Iterator<Worker> iterator = team.iterator();
while (iterator.hasNext()) {
Worker worker = iterator.next();
System.out.println("-------------");
System.out.println("이름: " + worker.getName());
System.out.println("직업: " + worker.getType().getValue());
}
}
}
결과
팀 이름: TF팀
-------------
이름: 이모씨
직업: 매니저
-------------
이름: 김모씨
직업: 개발자
-------------
이름: 송모씨
직업: 개발자
-------------
이름: 임모씨
직업: 기획자
-------------
이름: 장모씨
직업: QA
그렇다면 우리가 일반적으로 사용하는 ArrayList는?
ArrayList도 Collection을 구현했기 때문에 결국 최상위로 올라가 보면 Iterable을 구현하고 있는 것을 볼 수 있다.
알고 보면 우리도 모르게 ArrayList를 사용할 때마다 반복자 패턴을 사용하고 있던 것.
보통 이미 만들어진 Collection을 사용하지만, 커스터마이징 한 컬렉션을 사용해야 한다거나 직접 Iterator를 구현해서 반복하는 것이 효과적일 때 사용할 법하다.
Github 코드
참고 자료
1.쉽게 바로 써먹는 디자인 패턴 책
http://www.yes24.com/Product/Goods/93173296
'개발 > 디자인패턴' 카테고리의 다른 글
[Java][디자인 패턴] 16. 방문자 패턴 (Visitor Pattern) (0) | 2022.03.20 |
---|---|
[Java][디자인 패턴] 15. 명령 패턴 (Command Pattern) (0) | 2022.03.19 |
[Java][디자인 패턴] 13. 프록시 패턴 (Proxy Pattern) (0) | 2022.03.17 |
[Java][디자인 패턴] 12. 플라이웨이트 패턴 (Flyweight Patten) (0) | 2022.03.16 |
[Java][디자인 패턴] 11. 파사드 패턴 (Facade Pattern) (0) | 2022.03.12 |