[디자인패턴] Iterator

Judy·2022년 11월 16일
0

디자인패턴

목록 보기
5/11
post-thumbnail

Iterator

Behavioral Pattern

기본 표현(리스트, 스택, 트리 등)을 노출하지 않고 컬렉션의 요소를 순회할 수 있는 패턴


문제

Collection은 주로 사용되는 데이터 타입 중 하나입니다. 대부분의 컬렉션은 간단한 list를 저장하지만 일부는 stack, tree, graph 등 복잡한 데이터 구조를 기반으로 합니다.

어떤 컬렉션으로 구성되든 각 요소에 접근하는 방법을 제공해야 합니다. list 기반의 컬렉션이라면 쉬운 작업이 되겠지만 트리와 같은 복잡한 데이터를 순차적으로 탐색하려면 어떻게 할 수 있을까요?

어떤 상황에는 트리의 깊이 우선 탐색이 필요할 수도 있고, 다른 때에는 너비 우선 탐색 또는 임의 접근이 필요할 수도 있습니다.

이렇게 많은 순회 알고리즘을 컬렉션에 추가하다 보면 데이터 저장이라는 본래의 책임이 흐려지게 됩니다. 또한 일부 알고리즘은 특정 앱마다 다를 수 있으므로 일반적인 컬렉션 클래스에 포함하는 것은 문제가 될 수 있습니다.

반면에 다양한 컬렉션과 함께 동작하는 클라이언트 코드는 요소를 정장하는 방법에는 신경 쓰지 않을 수 있습니다. 그러나 컬렉션은 모두 해당 요소에 엑세스하는 다양한 방법을 제공해야 하므로 특정 클래스에 연결하는 방법밖에 없습니다.

해결

컬렉션의 순회 동작을 iterator라는 별도의 객체로 추출

알고리즘을 컬렉션 내부에서 구현하는 대신에 반복자 객체를 이용해 순회의 세부 사항은 캡슐화할 수 있습니다. 이런 방식으로 여러 반복자가 서로 독립적으로 존재하며 동일한 컬렉션을 거칠 수 있습니다.

일반적으로 반복자는 컬렉션 요소를 가져오는 기본 메서드를 제공합니다. 클라이언트는 아무 것도 반환하지 않을 때까지 즉 모든 요소를 순회할 때까지 이 메서드를 계속 실행할 수 있습니다.

모든 반복자는 동일한 인터페이스를 구현하여 클라이언트 코드가 모든 컬렉션 타입과 모든 순회 알고리즘을 사용할 수 있도록 합니다. 만약 컬렉션을 순회하는 특별한 방법이 필요한 경우 컬렉션이나 클라이언트를 변경할 필요 없이 새 반복자 클래스를 추가하면 됩니다.

현실 예제

로마에 여행을 간 당신은 주요 명소를 모두 방문할 계획입니다.

  1. 발이 닿는 곳으로 걷기
  2. 가이드 앱을 구비해 내비게이션으로 사용하기
  3. 가이드를 구하기

이런 모든 방법은 관광 명소 컬렉션에서 반복자 역할이 됩니다.

구조

1. Iterator 인터페이스

  • 컬렉션 순회에 필요한 작업 정의
  • ex) 현재 요소 검색, 다음 요소 가져오기, 반복 재시작 등

2. Iterator 구현

  • 컬렉션 순회를 위한 특정 알고리즘 구현
  • 순회 진행률을 자체적으로 추척 -> 여러 반복자가 독립적으로 컬렉션 탐색 가능

3. Collection 인터페이스

  • 컬렉션과 호환되는 반복자를 얻기 위한 하나 이상의 메서드 정의
  • 다양한 종류의 반복자를 사용할 수 있도록 해당 메서드가 반복자 인터페이스를 반환하도록 정의

4. Collection 구현

  • 클라이언트가 요청하면 특정 반복자의 인스턴스를 반환

5. Client

  • 인터페이스를 통해 컬렉션과 반복자를 사용
  • 동일안 코드로 다양한 컬렉션과 반복자를 사용 가능
  • 일반적으로는 컬렉션 객체에서 반복자 객체를 생성하지만 클라이언트가 직접 특수 반복자를 정의 가능

구현방법

  1. 순회에 필요한 메서드를 가지도록 반복자 인터페이스 정의 (다음 요소를 가져오는 메서드는 반드시 정의)
  2. 컬렉션 인터페이스를 정의 (반복자 인터페이스를 반환하는 메서드 정의)
  3. 반복자 객체를 구현. 반복자 객체는 하나의 컬렉션 인스턴스와 연결되어야 하는데 일반적으로 생성자를 통해 결정
  4. 컬렉션 객체를 구현. 특정 컬렉션에 따른 반복자 객체를 생성하는 메서드를 클라이어트에 제공. 반복자 생성자에 자신을 전
  5. 클라이언트의 컬렉션 순회 코드를 반복자 객체로 사용. 컬렉션 요소를 반복해야 할 때마다 새로운 반복자 객체를 가져오기

적용

  • 컬렉션이 복잡한 데이터 구조를 가졌지만 클라이언트에게 복잡성을 숨기려고 할 때 (편리상 또는 보안상의 이유)
  • 패턴을 사용해 순회 코드의 중복을 줄이고 싶을 때
  • 코드가 다른 데이터 구조를 순회할 수 있도록 하거나 순회할 데이터의 타입을 미리 알 수 없을 때

장단점

✅ 장점

  • 단일 책임 원칙(SRP) 준수 : 순회 알고리즘을 별도의 객체로 분리
  • 개방/폐쇄 원칙(OCP) 준수 : 새로운 타입의 컬렉션 및 새로운 반복자를 추가할 수 있음
  • 하나의 컬렉션에서 동시에 다른 방법의 순회가 가능
  • 순회를 연기하고 원할 때 다시 재개 가능

❎ 단점

  • 단순한 컬렉션만 사용하는 경우 패턴을 적용하는게 과잉일 수 있음
  • 반복자를 사용하는 것이 특수한 컬렉션을 직접 탐색하는 것보다 덜 효율적일 수 있음


참고 링크
iterator

profile
iOS Developer

0개의 댓글