명령패턴이란?
행위를 캡슐화하여 큐에 저장하거나 로그로 기록하고, 다시 재실행할 수 있는 패턴이다.
이로 인해 행동을 되돌리거나 하는 등의 시스템이 가능해진다.
이게 어떻게 가능한지 이해가 잘 안 된다.. 예제를 보면서 코드의 흐름을 이해해 보자
아이템 거래시스템에 명령패턴을 적용한 예제를 살펴보자
우선 거래명령이 구현해야 할 인터페이스를 정의해 주자.
public interface ICommand
{
void Execute();
void Undo();
}
그리고 거래명령받으면 실제로 아이템을 교환하는 플레이어를 만들자
public class Player : MonoBehaviour
{
public string playerName;
public List<string> inventory = new List<string>();
//아이템추가
public void AddItem(string item)
{
inventory.Add(item);
}
public void RemoveItem(string item)
{
// 아이템이 있으면
if (inventory.Contains(item))
{ //아이템 제거
inventory.Remove(item);
}
else
{
// 아이템이 없을때
}
}
}
그리고 명령 객체를 구현하자
public class TradeCommand : ICommand
{
private Player _sender;
private Player _receiver;
private string _item;
public TradeCommand(Player sender, Player receiver, string item)
{
_sender = sender;
_receiver = receiver;
_item = item;
}
public void Execute()
{ // 보내는쪽이 아이템을 들고있으면
if (_sender.inventory.Contains(_item))
{ // 지우고
_sender.RemoveItem(_item);
// 받는사람한테 추가하기
_receiver.AddItem(_item);
}
else
{
// 없으면 거래취소
}
}
// 되돌리기
public void Undo()
{ // 받은사람이 아이템 있는지 확인하고
if (_receiver.inventory.Contains(_item))
{ // 받은사람 아이템 지우고
_receiver.RemoveItem(_item);
// 준사람에게 아이템 추가하기
_sender.AddItem(_item);
}
else
{
// 원하는 대응
}
}
}
자 그러면 이렇게 캡슐화를 한 이유는 아래의 예제코드를 보면 알 수 있다.
public class TradeManager : MonoBehaviour
{
// 스택 자료구조로 저장하기에 후입선출방식
private Stack<ICommand> _tradeHistory = new Stack<ICommand>();
// 거래하라는 명령이 내려지면 거래를 시키고 기록함
public void ExecuteTrade(ICommand command)
{
command.Execute();
_tradeHistory.Push(command);
}
// 되돌리라는 명령이 내려지면 가장 마지막 기록을 가져와서 되돌림
public void UndoTrade()
{
if (_tradeHistory.Count > 0)
{
ICommand command = _tradeHistory.Pop();
command.Undo();
}
else
{
// 기록이 없습니다.
}
}
}
그리고 찐막으로 트레이드 매니저를 관리하면 끝
public class GameManager : MonoBehaviour
{
public Player player1;
public Player player2;
private TradeManager tradeManager;
private void Start()
{
tradeManager = new TradeManager();
player1.playerName = "geun";
player2.playerName = "hyun";
player1.AddItem("VeryGoodItem");
}
private void Update()
{
if (거래허락)
{
// 거래시도 (주는사람, 받는사람, 아이템)
var tradeCommand = new TradeCommand(player1, player2, "VeryGoodItem");
// 거래시키기
tradeManager.ExecuteTrade(tradeCommand);
}
if (거래 되돌리기)
{
// 마지막 거래를 되돌리기
tradeManager.UndoTrade();
}
}
}
이런 방법으로 행위를 캡슐화하여, 로그를 기록하고 언제든 되돌릴 수 있는 것이 명령패턴인 것 같다.
이런 방식으로 필요한 곳에 적절하게 사용하면 로그를 기록하거나 하는 방법도 쉽게 만들 수 있을 것 같다.
매번 디자인 패턴을 배울 때마다 드는 생각이지만
단일책임원칙만 잘 지키며 코딩해도 언제든 필요한 디자인패턴을 쉽게 적용할 수 있을 것 같다
'[UNITY],[C#] > TIL : UNITY' 카테고리의 다른 글
[Unity] JSON 유틸리티 이해하기 (0) | 2024.11.05 |
---|---|
[Unity] Mathf 함수 정리하기 (0) | 2024.11.04 |
[C#]딕셔너리를 알아보자 (0) | 2024.10.31 |
[디자인패턴] 이벤트 버스 패턴 (0) | 2024.10.30 |
[디자인패턴] 상태패턴 (0) | 2024.10.29 |