이 영역을 누르면 첫 페이지로 이동
나날이스튜디오 블로그 블로그의 첫 페이지로 이동

나날이스튜디오 블로그

페이지 맨 위로 올라가기

나날이스튜디오 블로그

나날이스튜디오의 일상, 아트/테크 노하우, 작품을 소개합니다.

Command Pattern

  • 2022.01.24 08:30
  • 개발/Design Pattern
글 작성자: 개발팀 임상우

# Introduce

오늘 소개드릴 디자인 패턴은 커맨드 패턴입니다.

커맨드 패턴은 실행될 기능을 캡슐화하여 재사용에 용이한 클래스를 구현하는 것을 말합니다.

 

어떤 객체(A)에서 다른 객체(B)의 메서드를 실행하려면 그 객체(B)를 참조하고 있어야 하는 의존성이 발생합니다.

그러나 커맨드 패턴을 적용하면 의존성을 제거할 수 있습니다.

 

 

 

 

#  Pros & Cons

장점

1. 작업을 요청하는 클래스(Invoker)와 실제로 작업을 수행하는 클래스(Receiver) 사이의 의존성이 사라집니다.

2. 기존 코드를 수정하지 않고 새로운 커맨드 및 기능을 쉽게 추가할 수 있습니다.

3. 커맨드 패턴을 통해 확장성이 높아질 수 있습니다.

 

단점

1. 모든 작업이 독립적인 ConcreteCommand 클래스이므로 구현 및 유지보수해야 하는 클래스가 많습니다.

2. 단 하나의 커맨드에 대해 클래스가 많아집니다.

 

# For example

- 무기를 작동시키는 커맨드 패턴 예시

 

1.  무기 클래스 (Receiver) 작성

//Receiver

public class Weapon
{
    //모든 무기에 공통적으로 들어가는 변수
    protected float damage;
    protected float coolTime;
}

public class Knife : Weapon
{
    //찌르기
    public void Stab()
    {
        Debug.Log("Stab");
    }
}


public class Gun : Weapon
{
    //총에 공통적으로 들어가는 변수
    protected int maxBulletCount;
    protected int nowBulletCount;
    protected float reloadCoolTime;
    protected float maxRange;

    //발사
    public virtual void Shoot()
    {
        Debug.Log("Shoot");
    }

    //재장전
    public virtual void Reload()
    {
        Debug.Log("Reload");
    }
}


public class Ak47 : Gun
{
    public override void Shoot()
    {
        Debug.Log("Ak47 Shoot");
    }

    public override void Reload()
    {
        Debug.Log("Ak47 Reload");
    }
}

 

2.  커맨드 클래스 작성

public interface IWeaponCommand
{
    void Execute();
}

public class ReloadGunCommand : IWeaponCommand
{
    private Gun gun;

    public void Execute()
    {
        //재장
        gun.Reload();
    }

    public ReloadGunCommand(Gun val)
    {
        gun = val;
    }
}

public class ShootGunCommand : IWeaponCommand
{
    private Gun gun;

    public void Execute()
    {
        //총쏘기
        gun.Shoot();
    }

    public ShootGunCommand(Gun val)
    {
        gun = val;
    }
}

public class StabKnifeCommand : IWeaponCommand
{
    private Knife knife;

    public void Execute()
    {
        //찌르기 실행
        knife.Stab();
    }

    public StabKnifeCommand(Knife val)
    {
        knife = val;
    }
}

 

3.  커맨드를 호출하는 클래스 (Invoker) 작성

//Invoker

using System.Collections.Generic;

public class CommandManager
{
    private Dictionary<string, IWeaponCommand> commandDic = new Dictionary<string, IWeaponCommand>();

    //커맨드를 세팅
    public void SetCommand(string name, IWeaponCommand command)
    {
        if (commandDic.ContainsValue(command))
        {
            Debug.Log("이미 커맨드가 포함되어있음.");
            return;
        }
        commandDic.Add(name, command);
    }

    //저장된 특정 커맨드를 실행
    public void InvokeExecute(string name)
    {
        commandDic[name].Execute();
    }
}

 

4.  커맨드 사용 클래스 작성

public class WeaponSystem : MonoBehaviour
{
    CommandManager commandMgr = null;

    void Start()
    {
        //Invoker
        commandMgr = new CommandManager();
        
        //Receiver
        M4A1 m4a1 = new M4A1();
        Knife knife = new Knife();

        //커맨드를 생성하고 연결
        ShootGunCommand shootM4a1Command = new ShootGunCommand(m4a1);
        ReloadGunCommand reloadM4a1Command = new ReloadGunCommand(m4a1);
        StabKnifeCommand stabKnifeCommand = new StabKnifeCommand(knife);

        //커맨드매니저에 커맨드를 세팅
        commandMgr.SetCommand("leftClick", shootM4a1Command);
        commandMgr.SetCommand("RKey", reloadM4a1Command);
        commandMgr.SetCommand("FKey", stabKnifeCommand);
    }

    void Update()
    {
        if(Input.GetMouseButton(0))
        {
            commandMgr.InvokeExecute("leftClick");
        }

        if(Input.GetKeyDown(KeyCode.R))
        {
            commandMgr.InvokeExecute("RKey");
        }

        if (Input.GetKeyDown(KeyCode.F))
        {
            commandMgr.InvokeExecute("FKey");
        }
    }
}

 

 

#  Epilogue

커맨드 패턴을 잘 활용하면 커맨드 활용에 대하여 유지 보수 및 활용도가 올라갑니다.

커맨드 패턴을 통하여 리플레이, undo 등 다양한 활용을 해보시길 바랍니다.

감사합니다.

 

# Reference

glikmakesworld.tistory.com/7 

 

유니티 디자인패턴 - 커맨드 (Unity Design Patterns - Command)

커맨드는 단어 그 자체로 본다면 명령, 요청이라는 뜻이다. 위키피디아를 보면 요청을 캡슐화한다고 써있는데, 쉽게 말하면 객체의 행동을 저장하고 필요할 때 꺼내 쓰는 방식이라고 보면 된다

glikmakesworld.tistory.com

rapapa.net/?p=3143

 

[ Pattern ] Command Pattern(명령 패턴) in Unity C# – Rapapa Dev Story

[ Programming Pattern 시리즈 ] 싱글턴 패턴 (Singleton Pattern) Link 컴포넌트 패턴 (Component Pattern) Link 커멘드 패턴 (Command Pattern) Link 관찰자 패턴 (Observer Pattern) Link 상태 패턴 (State Pattern) Link Part 1.  Command P

rapapa.net

 

korstrix.github.io/unity/unitylibrary/designpattern/github/Command_Pattern/

저작자표시 비영리 변경금지 (새창열림)

'개발 > Design Pattern' 카테고리의 다른 글

SendMessage로 FSM 구현해보기 (Unity3D)  (0) 2022.01.27
Singleton  (0) 2022.01.14

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • SendMessage로 FSM 구현해보기 (Unity3D)

    SendMessage로 FSM 구현해보기 (Unity3D)

    2022.01.27
  • Singleton

    Singleton

    2022.01.14
다른 글 더 둘러보기

정보

나날이스튜디오 블로그 블로그의 첫 페이지로 이동

나날이스튜디오 블로그

  • 나날이스튜디오 블로그의 첫 페이지로 이동

검색

메뉴

  • 🏠 홈
  • 🏷 태그
  • 📖 방명록

카테고리

  • 분류 전체보기 (14)
    • 나날이스튜디오 (7)
      • 팀 (1)
      • 일상 (6)
      • 작품 (0)
    • 개발 (7)
      • Design Pattern (3)
      • Github (0)
      • Unity3D (3)
    • 아트 (0)

최근 글

아카이브

정보

나날이스튜디오의 나날이스튜디오 블로그

나날이스튜디오 블로그

나날이스튜디오
    나날이스튜디오 블로그
    나날이스튜디오

    블로그 구독하기

    • 구독하기
    • RSS 피드

    방문자

    • 전체 방문자
    • 오늘
    • 어제

    티스토리

    • 티스토리 홈
    • 이 블로그 관리하기
    • 글쓰기
    Powered by Tistory / Kakao. © 나날이스튜디오. Designed by Fraccino.

    티스토리툴바