반복자 패턴
은 디자인 패턴 중 행동
패턴에 해당하며, 일련의 데이터 집합에 대하여 순차적
으로 접근 가능하게 해주는 패턴이다.▶︎ 데이터 집합
이란 객체들을 그룹으로 묶어 자료의 구조를 취하는 컬렉션을 말한다. 대표적인 컬렉션으로는 리스트, 트리, 그래프, 테이블 등이 있다.
Aggregate (집합체)
: Aggregate는 데이터 요소의 집합을 나타내는 인터페이스를 정의한다.
주로 반복자를 생성하는 메서드(createIterator())를 포함한다.
Aggregate 인터페이스를 구현한 구체적인 컬렉션 클래스에서 데이터 구조를 관리한다.
Iterator (반복자)
: Iterator는 Aggregate에서 정의한 인터페이스를 구현하며, 데이터 집합 내의 요소를 순회하고 접근하기 위한 메서드를 제공한다.주로 두 가지 메서드를 포함한다. 다음 요소로 이동하고 해당 요소를 반환하는 next() 메서드와 다음 요소의 존재 여부 확인하는 hasNext()가 있다.
ConcreteAggregate (구체적인 집합체)
: ConcreteAggregate는 Aggregate 인터페이스를 실제로 구현한 클래스로, 데이터 구조를 관리하고 Aggregate 인터페이스의 메서드를 구현한다.
구체적인 컬렉션(예: 리스트, 배열) 내의 데이터를 저장하고 관리한다.
반복자를 생성하여 ConcreteIterator 객체를 반환한다.
ConcreteIterator (구체적인 반복자)
: ConcreteIterator는 Iterator 인터페이스를 구현한 클래스로, 구체적인 컬렉션을 순회하고 요소에 접근하는 역할을 한다.
데이터 집합 내의 요소를 순차적으로 탐색하며, next() 메서드로 다음 요소로 이동하고 hasNext() 메서드로 순회 종료 여부를 확인한다.
반복자 패턴이 필요한 경우
- 컬렉션에 상관없이 객체 접근 순회 방식을 통일하고자 할 때
반복자 패턴의 장점
- 일관된 iterator interface를 사용해 여러 형태의 컬렉션에 대해 동일한 순회 방법을 제공한다.
반복자 패턴의 단점
- 클래스가 늘어나고 복잡도가 증가한다.
# 반복자(Iterator) 인터페이스 정의
class Iterator:
def __init__(self, collection):
self.collection = collection # 데이터 컬렉션을 저장합니다.
self.index = 0 # 현재 인덱스를 초기화합니다.
def next(self):
if self.has_next():
item = self.collection[self.index] # 현재 인덱스의 요소를 가져옵니다.
self.index += 1 # 인덱스를 다음으로 이동합니다.
return item
else:
raise StopIteration() # 더 이상 요소가 없으면 예외를 발생시킵니다.
def has_next(self):
return self.index < len(self.collection) # 다음 요소가 있는지 여부를 반환합니다.
# 숫자 목록 컬렉션 클래스 정의(Aggregate)
class NumberCollection:
def __init__(self):
self.data = [] # 데이터를 저장할 리스트를 초기화합니다.
def add(self, item):
self.data.append(item) # 숫자를 컬렉션에 추가합니다.
def create_iterator(self): # ConcreteIterator 생성
return Iterator(self.data) # 컬렉션에 대한 반복자를 생성하여 반환합니다.
# 클라이언트 코드
if __name__ == "__main__":
collection = NumberCollection() # 숫자 목록 컬렉션 객체를 생성합니다.
collection.add(1) # 숫자 1을 컬렉션에 추가합니다.
collection.add(2) # 숫자 2를 컬렉션에 추가합니다.
collection.add(3) # 숫자 3을 컬렉션에 추가합니다.
# ConcreteAggregate가 ConcreteIterator를 생성하는 부분
iterator = collection.create_iterator() # 컬렉션에 대한 반복자를 생성합니다.
print("숫자 목록 출력:")
while iterator.has_next():
print(iterator.next()) # 반복자를 사용하여 숫자 목록을 출력합니다.
from abc import ABC, abstractmethod
# 반복자(Iterator) 인터페이스 정의
class Iterator(ABC):
@abstractmethod
def next(self):
pass
@abstractmethod
def has_next(self):
pass
# Aggregate 인터페이스 정의
class Aggregate(ABC):
@abstractmethod
def create_iterator(self):
pass
# ConcreteAggregate 클래스 정의
class ConcreteNumberCollection(Aggregate):
def __init__(self):
self.data = [] # 데이터를 저장할 리스트를 초기화합니다.
def add(self, item):
self.data.append(item) # 숫자를 컬렉션에 추가합니다.
def create_iterator(self):
return ConcreteIterator(self) # ConcreteIterator를 생성하여 반환합니다.
# 구체적인 반복자(ConcreteIterator) 클래스 정의
class ConcreteIterator(Iterator):
def __init__(self, collection):
self.collection = collection
self.index = 0
def next(self):
if self.has_next():
item = self.collection.data[self.index] # 현재 인덱스의 요소를 가져옵니다.
self.index += 1 # 인덱스를 다음으로 이동합니다.
return item
else:
raise StopIteration() # 더 이상 요소가 없으면 예외를 발생시킵니다.
def has_next(self):
return self.index < len(self.collection.data) # 다음 요소가 있는지 여부를 반환합니다.
if __name__ == "__main__":
collection = ConcreteNumberCollection()
collection.add(1)
collection.add(2)
collection.add(3)
iterator = collection.create_iterator()
print("숫자 목록 출력:")
while iterator.has_next():
print(iterator.next()) # 반복자를 사용하여 숫자 목록을 출력합니다.