Gof의 디자인 패턴 - 반복자 패턴

Groot·2024년 6월 30일
0

TIL

목록 보기
147/153
post-thumbnail

반복자 패턴

  • 내부 구현을 노출하지 않고 어떤 집합 객체에 속한 원소들을 순회할 때 접근하는 방법 제공
  • 순회 방법이 바뀌는 것에 상관없이 외부에선 단순 함수로 접근할 수 있게 된다.

활용성

  • 객체 내부 표횬 방식을 모르고도 집합 객체의 각 원소들에 접근하고 싶을 때
  • 집합 객체를 순회하는 다양한 방법을 지원하고 싶을 때
    - 서로 다른 집합 객체 구조에 대해서도 동일한 방법으로 순회하고 싶을 때

구조

요소

  • Iterator: 원소를 접근하고 순회하는 데 필요한 인터페이스를 제공
  • ConcreteIterator : Iterator에 정의된 인터페이스를 구현하는 클래스, 순회 과정 중 집합 객체 내에서 현재 위치를 기억
  • Aggregate : Iterator에 객체를 생성하는 인터페이스 정의
  • ConcreteAggregate : 해당하는 ConcreteIterator의 인스턴스를 반환하는 Iterator생성 인터페이스를 구현

협력 방법

  • ConcreteIterator는 집합 객체 내 현재 객체를 계속 추적하고 다음번 방문할 객체를 결정

장점

  • 집합 객체의 다양한 순회방법 제공
    • 새로운 순회 방법을 Iterator 서브클래스로 정의하여 기존 순회 방법을 다른 알고리즘으로 교체
  • Iterator는 Aggregate의 인터페이스를 단순화
  • 순회 코드 중복 제거
  • 같은 컬렉션을 병렬 순회
  • 순회 지연 가능

단점

  • 단순 컬렉션을 사용할 땐 굳이..
  • 일부 특수 컬렉션의 요소를 직접 탐색하는것보다 덜 효율적일 수 있다.

예시 코드

protocol Iterator {
    associatedtype Element
    func hasNext() -> Bool
    func next() -> Element?
}

class ConcreteIterator<T>: Iterator {
    typealias Element = T
    
    private var collection: [T]
    private var index = 0
    
    init(_ collection: [T]) {
        self.collection = collection
    }
    
    func hasNext() -> Bool {
        return index < collection.count
    }
    
    // 순회 인터페이스 구현
    func next() -> T? {
        guard hasNext() else {
            return nil
        }
        let element = collection[index]
        index += 1
        return element
    }
}

// Aggregate가 필수일까?
protocol Aggregate {
    associatedtype Element
    func createIterator() -> ConcreteIterator<Element>
}

class ConcreteAggregate<T>: Aggregate {
    typealias Element = T
    
    private var items: [T]
    
    init(_ items: [T]) {
        self.items = items
    }
    
    func createIterator() -> ConcreteIterator<T> {
        return ConcreteIterator<T>(items)
    }
}

// 예제 데이터
let numbers = [1, 2, 3, 4, 5]

// ConcreteAggregate 인스턴스 생성
let numberAggregate = ConcreteAggregate(numbers)

// Iterator 생성
let iterator = numberAggregate.createIterator()

// Iterator를 사용하여 순회
while iterator.hasNext() {
    if let number = iterator.next() {
        print(number)
    }
}

https://developer.apple.com/documentation/swift/iteratorprotocol

참고

profile
I Am Groot

0개의 댓글