디자인 패턴

디자인 패턴 - 커맨드 패턴(Command pattern)에 대해 알아보자

근본넘치는개발자 2024. 11. 22. 23:57

2024.11.07 - [디자인 패턴] - 디자인 패턴 - MVC(Model-View-Controller)패턴에 대해 알아보자(+ MVP, MVVM)

 

 

오늘은 커맨드 패턴에 대해 알아보고자 합니다.

 

팀 프로젝트를 마무리하면서 팀원분의 코드를 보게 되었는데

퀵 슬롯을 Command 패턴을 활용하여 구현했다는 내용을 듣고 

오랜만에 디자인 패턴으로 글을 작성하게 되었습니다.

 

Command 패턴

각각의 요청을 캡슐화하여 명령을 객체화하는 디자인 패턴입니다.

 

명령을 보내는 객체와 받는 객체 간의 결합도를 낮출 수 있고,

명령을 추가할 때 새로운 Command 클래스를 추가하면

코드 수정 없이 기능 추가가 가능하다는 장점이 있습니다.

 

 

예시 코드

 

더보기
using UnityEngine;
using System.Collections.Generic;
using UnityEngine.Events;

// 커맨드 인터페이스
public interface ICommand
{
    void Execute();
}

// 기본 스킬 커맨드
public class SkillCommand : ICommand
{
    private readonly string skillName;
    private readonly UnityAction skillAction;

    public SkillCommand(string name, UnityAction action)
    {
        skillName = name;
        skillAction = action;
    }

    public void Execute()
    {
        Debug.Log($"Using skill: {skillName}");
        skillAction?.Invoke();
    }
}

// 아이템 사용 커맨드
public class ItemCommand : ICommand
{
    private readonly string itemId;
    private readonly UnityAction<string> useItemAction;

    public ItemCommand(string id, UnityAction<string> action)
    {
        itemId = id;
        useItemAction = action;
    }

    public void Execute()
    {
        Debug.Log($"Using item: {itemId}");
        useItemAction?.Invoke(itemId);
    }
}

// 퀵슬롯 매니저
public class QuickSlotManager : MonoBehaviour
{
    private Dictionary<KeyCode, ICommand> quickSlots = new Dictionary<KeyCode, ICommand>();

    private void Update()
    {
        foreach (var slot in quickSlots)
        {
            if (Input.GetKeyDown(slot.Key))
            {
                slot.Value?.Execute();
            }
        }
    }

    public void RegisterCommand(KeyCode key, ICommand command)
    {
        if (quickSlots.ContainsKey(key))
        {
            quickSlots[key] = command;
        }
        else
        {
            quickSlots.Add(key, command);
        }
    }

    public void UnregisterCommand(KeyCode key)
    {
        if (quickSlots.ContainsKey(key))
        {
            quickSlots.Remove(key);
        }
    }
}

// 사용 예시
public class Player : MonoBehaviour
{
    private QuickSlotManager quickSlotManager;

    private void Start()
    {
        quickSlotManager = GetComponent<QuickSlotManager>();
        
        // 스킬 등록
        quickSlotManager.RegisterCommand(KeyCode.Alpha1, 
            new SkillCommand("Fireball", () => CastFireball()));
            
        // 아이템 등록
        quickSlotManager.RegisterCommand(KeyCode.Alpha2, 
            new ItemCommand("HealthPotion", (itemId) => UseItem(itemId)));
    }

    private void CastFireball()
    {
        // 파이어볼 스킬 구현
        Debug.Log("Fireball cast!");
    }

    private void UseItem(string itemId)
    {
        // 아이템 사용 구현
        Debug.Log($"Used item: {itemId}");
    }
}

 

마무리 

오늘은 간단하게 Command 패턴에 대해 알아보았습니다.

위 예시 코드는 GPT에게 예시로 작성해달라고 한 코드입니다.

 

어느 정도 이해는 한 거 같은데

팀원분 코드를 한번 뜯어보면서 남는 시간에 개인적으로 더 공부해 봐야겠네요.

 

퀵 슬롯 말고도 콤보기능에서도 자주 사용되는 듯하니 

관심 있으신 분이라면 아래 참고 자료 링크를 타고 들어가서

제공하는 예제 프로젝트를 한번 확인해 보시는 것도 좋을 것 같습니다.

 

참고한 자료 

 

https://youtu.be/51sFAT2xZ40?si=qUrKMyFkwWLtw4Ay

https://www.youtube.com/live/j4kVuJQUMtw?si=GlJOsIj5I5FDUC0q