디자인패턴
반복자패턴
khkg12
2023. 11. 23. 15:34
반복자패턴이란?
일련의 데이터 집합에서 순차적인 접근을 제공해주는 패턴이다. IEnumerator를 상속받은 순서에 대한 클래스를 만들어주고 그 순서로 컬렉션을 반복할 수 있게 해주는 것이다. 예시로 카드덱 클래스가 있을 때 카드덱에 대한 순서의 의미를 가진 클래스를 구현하고, 그 순서를 받아 커스텀한 순차대로 카드를 출력하는 것이다.
예시코드
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class Card
{
public string name;
public int cost;
public Card(string name, int cost)
{
this.name = name;
this.cost = cost;
}
}
public class Deck : List<Card>
{
public class DeckEnumerator : IEnumerator // 클래스 내부의 컬렉션에 대해 반복할 수 있도록 해주는 인터페이스, 이를 상속받아 커스텀
{
List<Card> cards;
public event Action onEmpty;
int curIndex = -1;
public DeckEnumerator(Deck deck)
{
cards = deck;
}
public object Current => cards[curIndex];
public bool MoveNext()
{
curIndex++;
bool isEmpty = curIndex >= cards.Count;
if (isEmpty)
onEmpty?.Invoke(); // 비어있을 때! 호출되는 이벤트
return !isEmpty;
}
public void Reset()
{
curIndex = -1;
}
}
public new DeckEnumerator GetEnumerator() // 컬렉션의 반복자를 리턴하는 함수
{
return new DeckEnumerator(this);
}
}
public class DeckController : MonoBehaviour
{
Deck deck;
public int hp = 30;
public int reduceHp = 1;
Deck.DeckEnumerator deckEnumerator;
void Start()
{
deck = new Deck();
deck.Add(new Card("강타", 3));
deck.Add(new Card("이글거리는도끼", 2));
deck.Add(new Card("방패올리기", 3));
deckEnumerator = deck.GetEnumerator(); // 반복자 저장
deckEnumerator.onEmpty += () => {
Debug.Log("카드가 다 떨어졌습니다.");
hp -= reduceHp++;
};
}
void Draw()
{
if (deckEnumerator.MoveNext())
{
Card drawCard = (Card)deckEnumerator.Current;
Debug.Log(drawCard.name);
}
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Draw();
}
}
}