[디자인 패턴] 반복자 패턴_Iterator pattern (JavaScript)

2024. 11. 17. 21:57Web_Programming

 

Iterator 패턴이란?

Iterator Pattern은 데이터 컬렉션의 내부 구조를 숨기면서 클라이언트가 일관된 방식으로 데이터에 순차적으로 접근할 수 있도록 도와주는 디자인 패턴입니다. 이 패턴은 단일 책임 원칙을 따르며, 데이터 집합체의 내부 구현과 데이터 순회 방법을 분리하여 결합도를 낮추고 코드의 확장성을 높입니다.

구성요소

  • IterableCollection (Aggregate)
    컬렉션을 순회할 이터레이터를 생성하는 인터페이스를 정의합니다.
    • createIterator(): ConcreteIterator 객체를 반환하는 팩토리 메서드.
  • ConcreteCollection (ConcreteAggregate)
    데이터 집합체를 구현하며, 이터레이터를 반환하는 메서드를 제공합니다.
  • Iterator (Interface)
    데이터 집합체를 순회하기 위한 인터페이스를 정의합니다.
    • next(): 다음 요소를 반환하고, 커서를 이동합니다.
    • hasNext(): 더 순회할 요소가 있는지 여부를 반환합니다.
  • ConcreteIterator
    데이터 집합체를 순회하며, 순회 전략을 구현합니다.
    데이터의 실제 순회 로직을 구체화하여, 데이터 구조의 복잡성을 클라이언트로부터 숨깁니다.

예시 코드

// Iterator 인터페이스
interface Iterator<T> {
  next(): T | null; // 다음 요소를 반환
  hasNext(): boolean; // 다음 요소 여부 확인
}

// Aggregate 인터페이스
interface Aggregate<T> {
  createIterator(): Iterator<T>;
}

// Product 클래스 (데이터 요소)
class Product {
  constructor(public name: string, public price: number, public inStock: boolean) {}
}

// ProductCollection 클래스 (ConcreteAggregate)
class ProductCollection implements Aggregate<Product> {
  private products: Product[] = [];

  addProduct(product: Product): void {
    this.products.push(product);
  }

  createIterator(): Iterator<Product> {
    return new ProductIterator(this.products);
  }
}

// ProductIterator 클래스 (ConcreteIterator)
class ProductIterator implements Iterator<Product> {
  private index = 0;

  constructor(private products: Product[]) {}

  next(): Product | null {
    if (this.hasNext()) {
      return this.products[this.index++];
    }
    return null;
  }

  hasNext(): boolean {
    return this.index < this.products.length;
  }
}

// 사용 예시
const productCollection = new ProductCollection();
productCollection.addProduct(new Product("Laptop", 1500, true));
productCollection.addProduct(new Product("Phone", 800, false));
productCollection.addProduct(new Product("Tablet", 1200, true));

const iterator = productCollection.createIterator();

while (iterator.hasNext()) {
  const product = iterator.next();
  if (product) {
    console.log(`${product.name} - $${product.price}`);
  }
}

 

 

Laptop - $1500
Phone - $800
Tablet - $1200

장단점

장점

  1. 일관된 인터페이스 제공
    다양한 데이터 컬렉션에 대해 동일한 순회 방식을 사용할 수 있습니다.
  2. 내부 구조 은닉
    클라이언트는 데이터 구조의 복잡한 구현을 알 필요 없이 데이터를 순회할 수 있습니다.
  3. 단일 책임 원칙
    데이터 저장소(컬렉션)와 데이터 순회를 분리하여 각 클래스의 책임을 명확히 합니다.
  4. 개방/폐쇄 원칙 준수
    데이터 구조가 변경되어도 클라이언트 코드는 수정이 필요 없습니다.

단점

  1. 복잡도 증가
    이터레이터 클래스를 추가로 작성해야 하므로 클래스의 수가 늘어나고 복잡도가 증가합니다.
  2. 메모리 사용량 증가
    대규모 데이터셋에서는 추가적인 이터레이터 객체 생성으로 메모리 사용량이 늘어날 수 있습니다.

Iterator Pattern은 데이터 컬렉션의 내부 동작을 숨기면서 클라이언트 코드의 단순성과 확장성을 유지하는 데 유용합니다. 특히, 다양한 데이터 구조를 처리하는 애플리케이션에서 매우 효과적입니다.

반응형