Iterator Pattern 🧙♂️
디자인 패턴이란?
디자인 패턴이란?
- 디자인 패턴은 소프트웨어 공학의 소프트웨어 설계에서 공통으로 발생하는 문제를 자주 쓰이는 설계 방법을 정리한 패턴이다.
- 디자인 패턴을 참고하여 개발하면 효율성과 유지보수성, 운용성이 높아지며, 프로그램 최적화가 된다고 한다.
디자인 패턴을 목적과 범위로 나눌수 있다
구분 | 유형 | 설명 |
---|---|---|
생성 | 객체 인스턴스 생성에 관여, 클래스 정의와 객체 생성 방식을 구조화, 캡슐화를 수행 | |
목적 | 구조 | 더 큰 구조 형성 목적으로 클래스나 객체의 조합을 다루는 패턴 |
행위 | 클래스나 객체들이 상호작용하는 방법과 역할 분담을 다루는 패턴 | |
범위 | 클래스 | 클래스간 관련성(상속), 컴파일 시 정적으로 결정 |
객체 | 객체 간 관련성을 다루는 패턴, 런타임 시 동적으로 결정 |
이터레이터 패턴
반복작업을 이터레이터에게 맡겨서 반복작업을 순서대로 처리하는 패턴
이터레이터 패턴
반복작업을 이터레이터에게 맡겨서 반복작업을 순서대로 처리하는 패턴 {: .prompt-tip}##<span style="color: gold">
이터레이터 패턴이란? Iterator pattern
이터레이터 패턴은 컬렉션 구현 방법을 노출시키지 않으면서도 그 집합체 안에 들어있는 모든 항목에 대해 접근할 수 있게 해준다. 또한, 모든 항목에 일일이 접근하는 컬랙션 객체가 아닌 반복자 객체가 맡고 진행한다는 점이다.(Stream같은 내부반복자는 아님) 이를 통해 인터페이스와 구현이 단순해진다. 우선 이터레이터의 기본 사용법을 설명하고 이터레이터 패턴을 알아보자.
이터레이터 기본 구성
1
2
3
4
5
6
7
8
9
10
11
12
13
class AboutIterator{
public static void main (String[] args){
ArrayList list = new ArrayList();
list.add("1"); ... list.add("5"); // 1~5까지 넣었다고 가정
Iterator it = list.iterator();
while(it.hasNext()){
Object obj = it.next();
System.out.print(obj+" "); //1 2 3 4 5
}
}
}
한 방향으로만 사용하는 이터레이터 외에 반대방향으로도 하는 사용할 수 있는 List iterator도 있다. next()대신 preivous()
를 사용하면된다.
리스트 이터레이터 구성
ListIterator
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class AboutIterator{
public static void main (String[] args){
ArrayList list = new ArrayList();
list.add("1"); ... list.add("5"); // 1~5까지 넣었다고 가정
ListIterator it = list.listIterator();
while(it.hasNext()){
Object obj = it.next();
System.out.print(obj+" "); //1 2 3 4 5
}
while(it.hasPrevious()){
Object obj = it.pervious();
System.out.print(obj+" "); //5 4 3 2 1 역방향
}
}
}
자 이번에는 이터레이터 패턴을 이용해보겠다. 필자는 요새 향수가 너무 많아서 향수를 한번 정리하는겸 향수로 예제를 만들겠다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import java.util.Iterator;
//까먹지 않고 이터레이터를 쓰기 위한 인터페이스
interface makeIteratorInterface{
Iterator createIterator();
}
//향수이름과 브랜드를 저장하는 객체
public class Perfume {
private String name;
private String brand;
public String getName() {
return name;
}
public String getBrand() {
return brand;
}
public Perfume(String brand, String name) {
this.name = name;
this.brand = brand;
}
//향수를 보관하는 수납장이다.
private static class Closet implements makeIteratorInterface{
private Perfume[] perfumes;
private int location = 0; //향수 마지막 위치
public Perfume getPerfume(int location) {
return perfumes[location];
}
public int getLocationSize() {
return location;
}
public void collectPerfume(Perfume perfume) {
if (location < perfumes.length) {
this.perfumes[location] = perfume;
location++;
}else
System.out.println("수납장이 꽉찼습니다.");
}
public Closet(int total) { //향수 총개수
perfumes = new Perfume[total];
}
@Override
public Iterator createIterator() {
return new ClosetIterator(this);
}
수납장에서 하나씩 애들을 어떻게 꺼낼지 정책을 결정하는 이터레이터 패턴의 예.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private class ClosetIterator implements Iterator<Perfume> {
private Closet closet;
private int currentLocation = 0;
public ClosetIterator(Closet closet) {
this.closet = closet;
}
@Override
public boolean hasNext() {
return currentLocation < closet.getLocationSize();
}
@Override
public Perfume next() {
Perfume perfume = closet.getPerfume(currentLocation);
currentLocation++;
return perfume;
}
}
정답을 출력하는 메서드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public static void main(String[] args) {
Closet closet = new Closet(4);
Perfume perfume1 = new Perfume("입셍로랑", "옴므");
Perfume perfume2 = new Perfume("베르사체", "에로스");
Perfume perfume3 = new Perfume("디올", "세비지");
Perfume perfume4 = new Perfume("샤넬", "옴므");
Perfume perfume5 = new Perfume("에르메스", "옴므");
closet.collectPerfume(perfume1); closet.collectPerfume(perfume2);
closet.collectPerfume(perfume3); closet.collectPerfume(perfume4);
closet.collectPerfume(peffume5);
System.out.println("현재 향수 개수 = " + closet.getLocationSize());
Iterator iterator = closet.createIterator();
while (iterator.hasNext()) {
Perfume next = (Perfume) iterator.next();
System.out.println(next.brand+" "+next.name);
}
}
}
}
//수납장이 꽉찼습니다. (에르메스가 못들어감.)
//현재 향수 개수 = 4
// 입셍로랑 옴므
// 베르사체 에로스
// 몽블랑 세비지
// 샤넬 옴므
<span style="color: gold">
장점 단점
장점
- 위에서 언급한 것처럼 모든 항목을 일일히 접근하여 작업을 하는 것이 아닌, 이터레이터가 모든 항목에 대해 접근할 수 있도록 해준다.
- 클래스의 응집도가 올라간다. (응집도: 한 모듈 내부의 처리 요소들이 서로 관련되어 있는 정도)
단점
- 사실 지금과 같은 단순한 반복이라면 복잡하기만하고 필요성이 없는거 같다.
<span style="color: gold">
출처
- Head First 디자인패턴