메모. Iterator pattern
이터레이터 패턴(Iterator pattern)은 가장 간단하면서도, 자주 사용되는 디자인 패턴 중 하나다. 이 패턴은 컬렉션이나 집합 객체의 내부적인 구현 방법을 드러내지 않으면서도 그 안에 있는 모든 원소에 순차적으로 접근할 수 있는 수단을 제공한다.
이터레이터 패턴의 UML 클래스 다이어그램
- Iterator: 원소를 접근하고 순회하는 데 필요한 인터페이스를 제공한다. (다음 요소를 가져오거나, 현재의 위치를 찾거나, 다시 반복을 시작하는 등의 연산)
- ConcreteIterator: Iterator에 정의된 인터페이스를 구현하는 클래스. 순회 과정 중 집합 객체 내에서 현재 위치를 기억한다.
- IterableCollection: Iterator 객체를 생성하는 인터페이스를 정의한다.
- ConcreteCollection: 해당하는 ConcreteIterator의 인스턴스를 반환하는 Iterator 생성 인터페이스를 구현한다.
장점
- 구조가 복잡한 집합 객체 내에서 어떤 식으로 일이 처리되는지에 대해서 전혀 모르는 상태에서 그 안에 있는 들어있는 모든 항목들에 대해 반복 작업을 수행할 수 있다.
- 컬렉션 객체 내에 들어있는 모든 항목에 접근하는 방식이 통일되어 있으므로 어떤 종류의 집합체에 대해서도 사용할 수 있는 다형적인 코드를 만들 수 있다.
- 모든 항목에 일일이 접근하는 작업을 컬렉션 객체가 아닌 이터레이터 객체에서 맡게 된다. 이렇게 하면, 집합체의 인터페이스 및 구현이 간단해질 뿐만 아니라, 집합체에서는 반복 작업에서 손을 떼고 원래 자신이 할 일에만 전념할 수 있다.
예제 코드
// Iterator: https://refactoring.guru/design-patterns/iterator
using System;
using System.Collections;
using System.Collections.Generic;
namespace RefactoringGuru.DesignPatterns.Iterator.Conceptual
{
abstract class Iterator : IEnumerator
{
object IEnumerator.Current => Current();
public abstract int Key();
public abstract object Current();
public abstract bool MoveNext();
public abstract void Reset();
}
abstract class IteratorAggregate : IEnumerable
{
public abstract IEnumerator GetEnumerator();
}
class AlphabeticalOrderIterator : Iterator
{
private WordsCollection _collection;
private int _position = -1;
private bool _reverse = false;
public AlphabeticalOrderIterator(WordsCollection collection, bool reverse = false)
{
this._collection = collection;
this._reverse = reverse;
if (reverse)
{
this._position = collection.getItems().Count;
}
}
public override object Current()
{
return this._collection.getItems()[_position];
}
public override int Key()
{
return this._position;
}
public override bool MoveNext()
{
int updatedPosition = this._position + (this._reverse ? -1 : 1);
if (updatedPosition >= 0 && updatedPosition < this._collection.getItems().Count)
{
this._position = updatedPosition;
return true;
}
else
{
return false;
}
}
public override void Reset()
{
this._position = this._reverse ? this._collection.getItems().Count - 1 : 0;
}
}
class WordsCollection : IteratorAggregate
{
List<string> _collection = new List<string>();
bool _direction = false;
public void ReverseDirection()
{
_direction = !_direction;
}
public List<string> getItems()
{
return _collection;
}
public void AddItem(string item)
{
this._collection.Add(item);
}
public override IEnumerator GetEnumerator()
{
return new AlphabeticalOrderIterator(this, _direction);
}
}
class Program
{
static void Main(string[] args)
{
var collection = new WordsCollection();
collection.AddItem("하나");
collection.AddItem("둘");
collection.AddItem("셋");
Console.WriteLine("정방향 순회:");
foreach (var element in collection)
{
Console.WriteLine(element);
}
Console.WriteLine("\n역방향 순회:");
collection.ReverseDirection();
foreach (var element in collection)
{
Console.WriteLine(element);
}
}
}
}
'프로그래밍 관련 > 객체 지향 설계' 카테고리의 다른 글
정리. SOLID 원칙 (0) | 2022.01.21 |
---|---|
메모. Command pattern (0) | 2019.11.26 |
메모. Proxy pattern (0) | 2019.11.18 |
메모. Facade pattern (0) | 2019.11.17 |
메모. Factory method pattern (0) | 2019.05.19 |