GoF의 디자인 패턴, 반복자 패턴에 대해 알아본다.
해당 글은, 다음의 코드를 기반으로 이해하는 것이 편리합니다.
핵심 요약
- 동일한 패턴의 데이터를 가지고 있는 것을 순회하기 위한 패턴
- 즉, Container/Aggregator 라 불리는 자료구조에 대해 순회
- Array, Linked List, Tree, Graph, Table(DBMS)
- 각 자료구조는 다음 데이터를 가져오는 방법이 달라짐 (구현 방식이 다르니)
- 이를 하나의 패턴으로 처리할 수 있도록 한 것
예시

Code
main
import Foundation
internal func main() {
let items = [
Item(name: "Bitcoin", cost: 23000),
Item(name: "Tesla", cost: 170),
Item(name: "Jordan", cost: 200),
Item(name: "CyberTruck", cost: 50000)
]
let array = Array(items: items)
let iterator = array.iterator
while iterator.next {
guard let current = iterator.current as? Item else {
break
}
print(current.description)
}
}
main()
Object
import Foundation
internal protocol Object {
}
Aggregator
import Foundation
internal protocol Aggregator {
var iterator: Iterator { get }
}Iterator
import Foundation
internal protocol Iterator {
var next: Bool { get }
var current: Object? { get }
}Loggable
import Foundation
internal protocol Loggable {
var description: String { get }
}
Item
import Foundation
internal class Item: Object {
internal init(name: String, cost: Int) {
self.name = name
self.cost = cost
}
private let name: String
private let cost: Int
}Array
import Foundation
internal class Array: Aggregator, Object {
internal init(items: [Item]) {
self.items = items
}
internal var iterator: Iterator {
ArrayIterator(array: self)
}
internal var count: Int {
self.items.count
}
internal func item(at index: Int) -> Item? {
guard index < self.items.count else {
return nil
}
return self.items[index]
}
private var items = [Item]()
}
ArrayIterator
import Foundation
internal class ArrayIterator: Iterator {
internal var next: Bool {
self.index += 1
return self.index < self.array.count
}
internal var current: Object? {
self.array.item(at: self.index)
}
internal init(array: Array) {
self.array = array
self.index = -1
}
private var array: Array
private var index: Int
}활용성
- 객체 내부 표현 방식을 모르고도 집합 객체의 각 원소들에 접근하고 싶을 때
- 집합 객체를 순회하는 다양한 방법을 지원하고 싶을 때
- 서로 다른 집합 객체 구조에 대해서도 동일한 방법으로 순회하고 싶을 때
결과
- 집합 객체의 다양한 순회방법을 제공한다.
- 다양한 Iterator를 추가하면 된다.
- Aggregater의 인터페이스를 단순화할 수 있다.
생각해볼 점
- 배열, 링크드리스트, 트리들과 같은 다양한 형태의 컨테이너에 대해
- 표준화된 공통 API를 제공할 수 있다는 점이 핵심
- 한개의 API만으로도 다양한 형태의 컨테이너 안 데이터에 접근할 수 있다.