참치코더의 꿈 메모장

디자인 패턴 / 반복자 패턴 정리(코드 위주) 본문

디자인 패턴

디자인 패턴 / 반복자 패턴 정리(코드 위주)

참치깡 2025. 10. 16. 11:17
728x90

 

반복자 패턴(Iterator)은 객체 집합의 내부 표현(배열, 연결리스트 등)에 상관없이 그 요소들에 

순차적으로 접근하는 방법을 제공하는 패턴이다.

 

- List, Set 같은 컬렉션 프레임워크의 내부 구조를 신경쓰지 않고, 같은 방식으로 요소를 순회할 수 있게

  해주는 패턴

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// Iterator 인터페이스, 순회 인터페이스
 
public interface Iterator<T> {
    boolean hasNext();
    T next();
}
 
// Aggregate 인터페이스. Iterator를 생성하는 인터페이스
 
public interface Aggregate<T> {
    Iterator<T> createIterator();
}
 
 
// 구체적인 집합체 클래스
import java.util.ArrayList;
import java.util.List;
 
public class BookCollection implements Aggregate<Book> {
    
    private List<Book> books = new ArrayList<>();
 
    public void addBook(Book book){
        book.add(book);
    }
}
 
// Book 클래스
public class Book {
    private String title;
 
    public Book(String title) { // 생성자
        this.title = title;
    }
 
    public String getTitle() { // getter
        return title;
    }
}
 
// 실제 Iterator 구현체
import java.util.List;
 
public class BookIterator implements Iterator<Book> {
    private List<Book> books;
    private int index = 0;
 
    public BookIterator(List<Book> books){
        this.books = books;
    }
 
    @Override
    public boolean hasNext() {
        return index < books.size();
    }
 
    @Override
    public Book next() {
        return books.get(index++);
    }
}
 
// 클라이이언트 코드
public class Main {
    public static void main(String[] args) {
        BookCollection collection = new BookCollection();
        collection.addBook(new Book("A"));
        collection.addBook(new Book("B"));
        collection.addBook(new Book("C"));
 
        // 여기가 중요, Book 컬렉션에 책을 저장한 후에 Iterator 메서드를 호출한다
        // Iterator 구현체이기 때문에 가능
        Iterator<Book> iterator = collection.createIterator(); 
 
        while (iterator.hasNext()){
            System.out.println(iterator.next().getTitle());
        }
    }
}
 
cs

 

 

스프링부트 예시

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
public interface NotificationSender {
    void send(String message);
}
 
@Component
public class EmailSender implements NotificationSender {
    public void send(String message){
        System.out.println("이메일 전송: " + message);
    }
}
 
@Component
public class SmsSender implements NotificationSender {
    public void send(String message){
        System.out.println("SMS 전송: " + message);
    }
}
 
@Service
public class NotificationService {
    
    private final List<NotificationSender> senders;
 
    public NotificationService(List<NotificationSender> senders){
        this.senders = senders; // 스프링이 모든 구현체 주입
    }
 
    public void notifyAll(String message){
        Iterator<NotificationSender> iterator = senders.iterator();
        while (iterator.hasNext()){
            iterator.next().send(message);
        }
    }
}
cs

 

 

왜 사용하나?

 

- ArrayList, HashMap, Map 등은 내부 구조가 다 다르다.

- 그런데 반복자 패턴을 사용하면 구조가 달라도 동일한 방식으로 순회가 가능해진다.

- 안에 어떤 컬렉션 패턴이든 hasNext() / next() 로 다 순차적으로 돌릴 수 있다.

728x90
Comments