이터레이터 패턴
컬렉션(예: 리스트, 스택, 트리 등)의 요소를 순회하는 표준 방법을 제공하는 디자인 패턴. 집합 객체를 순회하는 클라이언트 코드를 변경하지 않고 컬렉션들에 접근할 수 있는 다양한 순회 방법을 제공한다.
구조
- Iterator - 다음 요소에 접근하거나, 다음 요소가 있는지 확인하는 메소드 등을 정의한다.
- ConcreteIterator - Iterator 인터페이스를 구현하는 클래스. 컬렉션의 특정 구현 방식(예: 배열, 연결 리스트)에 따라 이터레이터의 순회 로직을 구현한다.
- Aggregate -Iterator 객체를 생성하는 메소드를 정의하는 클래스.
- ConcreteAggregate -Aggregate 인터페이스를 구현하는 클래스. 실제 컬렉션을 관리하며, 해당 컬렉션에 대한 Iterator를 생성하는 로직을 포함한다.
기본 인터페이스
public interface IIterator<T>
{
bool HasNext();
T Next();
}
public class ConcreteIterator<T> : IIterator<T>
{
private readonly List<T> _collection;
private int _currentIndex = 0;
public ConcreteIterator(List<T> collection)
{
_collection = collection;
}
public bool HasNext()
{
return _currentIndex < _collection.Count;
}
public T Next()
{
if (!HasNext())
{
throw new InvalidOperationException("No more elements in collection");
}
return _collection[_currentIndex++];
}
}
public interface IAggregate<T>
{
IIterator<T> CreateIterator();
}
public class ConcreteAggregate<T> : IAggregate<T>
{
private readonly List<T> _collection = new List<T>();
public IIterator<T> CreateIterator()
{
return new ConcreteIterator<T>(_collection);
}
public void Add(T item)
{
_collection.Add(item);
}
}
class Program
{
static void Main(string[] args)
{
var aggregate = new ConcreteAggregate<string>();
aggregate.Add("Item 1");
aggregate.Add("Item 2");
aggregate.Add("Item 3");
var iterator = aggregate.CreateIterator();
while (iterator.HasNext())
{
var item = iterator.Next();
Console.WriteLine(item);
}
}
}
왜 사용해야 할까?
이 패턴의 핵심은 컬렉션의 순회 로직을 컬렉션 자체로부터 분리하는 것이다. 이로 인해 컬렉션의 구현 방식이 변경되더라도, 클라이언트 코드는 영향을 받지 않는다. 클라이언트는 일관된 방식으로 다양한 컬렉션 타입을 처리할 수 있다.
이터레이터 패턴은 이터레이터(Iterator)와 집합체(Aggregate) 두 구성 요소로 이루어져 있다.
이터레이터는 컬렉션의 요소에 접근하고 순회하는 인터페이스를 제공한다. 이 인터페이스는 일반적으로 next(), hasNext() 같은 메서드를 포함하여, 컬렉션의 다음 요소를 검색하고, 더 이상 요소가 없는지 확인한다.
public interface IIterator<T>
{
bool HasNext();
T Next();
}
집합체는 이터레이터 인스턴스를 생성하는 역할을 하며, 실제 컬렉션 데이터를 관리한다.
public interface IAggregate<T>
{
IIterator<T> CreateIterator();
}
장점
- 집합 객체의 컬렉션을 캡슐화할 수 있다.
- 일관된 인터페이스를 사용하여 여러 형태의 집합 구조를 순회할 수 있다.
- 집합 객체가 가지고 있는 객체들에 대해 손쉽게 접근할 수 있다
단점
- 간단한 컬렉션에 대해 이터레이터 패턴을 사용하면 불필요한 오버헤드가 발생할 수 있다.
- 클래스가 늘어나고 복잡도가 증가한다.
참고자료
GoF의 디자인 패턴 - 예스24
이 책은 디자인 패턴을 다룬 이론서로 디자인 패턴의 기초적이고 전반적인 내용을 학습할 수 있다.
www.yes24.com
'프로그래밍 이론 > 디자인 패턴' 카테고리의 다른 글
18. [Design Pattern] 중재자(Mediator) 패턴 (0) | 2024.01.22 |
---|---|
17. [Design Pattern] 전략(Strategy) 패턴 (0) | 2024.01.17 |
15. [Design Pattern] 인터프리터(interpreter) 패턴 (0) | 2024.01.14 |
14. [Design Pattern] 커맨드(Command) 패턴 (0) | 2024.01.09 |
13. [Design Pattern] 책임 연쇄(Chain of Responsibility) 패턴 (1) | 2024.01.06 |