◽️ 커맨드 패턴
행위 패턴 중 하나로 실행될 기능을 캡슐화
함으로써 주어진 여러 기능을 실행할 수 있는 재사용성이 높은 클래스를 설계하는 패턴
- 커맨드 패턴을 이용해 요청 내역을 객체로 캡슐화 할 수 있고, 매개변수를 사용해 여러 가지 다른 요청을 집어 넣을 수 있음
- 또한 요청 내역을 큐에 저장하거나 로그로 기록할 수 있고, 작업취소 기능도 지원이 가능
- 요청을 하는 객체와(요청), 그 요청을 수행하는 객체(동작)를 분리 할 수 있음
- 리시버에 대한 동작이 추가될 때마다 잡다한 클래스가 많이 추가될 수 있다는 단점이 있음
- 요청 자체를 리시버한테 넘기지 않고 자신이 처리하는 스마트 커맨드 객체도 종종 사용
이런 커맨드 패턴을 구성하는 객체에는Client
, Command(명령)
, ConcreteCommand(구체적인 명령)
, Receiver(수신자)
, Invoker(호출자)
가 있다.
이런 식으로 실행될 기능을 캡슐화
함으로써 기능의 실행을 요구하는 호출자 클래스와 실제 기능을 실행하는 수신자 클래스 사이의 의존성을 제거함
따라서 실행될 기능의 변경되어도 호출자 클래스를 수정 없이 그대로 사용 할 수 있다.
커맨드 패턴은 식당에서 음식을 주문하는 프로세스와 흡사한데 한번 예시를 보자!
국밥집 in 객체 마을
객체 마을에도 한 국밥집이 있다. 기본적인 운영 흐름은 일반적인 식당과 같다.
- 손님이 웨이터에게 주문을 한다.
- 웨이터가 고객의 주문을 주문서에 적는다.
- 웨이터는 주문서를 주방에 전달하여 주문을 요청한다.
- 요리사는 주문서에 적힌 주문대로 음식을 만든다.
객체 마을이니 만큼 객체와 메소드를 사용해 주문을 처리한다.
식당 | 커맨드 패턴 |
---|
손님 | 클라이언트 |
웨이터 | 인보커 객체 |
주문서 | 커맨드 객체 |
주방장 | 리시버 객체 |
음식 주문 | setCommand() |
주문 요청 | execute() |
이런 식으로 커맨드 패턴과 상응해서 동작하는 것을 알 수 있다!
언제 쓰면 좋을까?
야곰닷넷 - 커맨드 패턴 언제 사용할까?
- 자주 사용하는 기능들을 커맨드 패턴을 이용해서 만들면 재사용이 쉬워지면서 객체간 결합도도 낮출 수 있다.
- 엑셀에서 원하는 데이터를 찾는 방법
도구 모음의 찾기 버튼, 메뉴에서 찾기, Command+F / Ctrl+F
- UI로직과 비즈니스 로직을 연결할 때
- Command는 다양한 입력 방식(저장 버튼, 키보드 단축키 등등)과 저장 기능을 가진 비즈니스 로직 개체 간의 중간다리 역할을 한다.
- UI 개체들은 어떤 비즈니스 로직이 요청을 수신하고 처리하는지 알 필요 없이 Command의 명령을 실행하기만 하면 된다.
즉 작업을 캡슐화
해서 Receiver에게 보내서 처리하고 싶을 때 사용하면 좋다.
커맨드 패턴 in Swift
커맨드 패턴을 사용해 TV를 껐다 킬 수 있고 채널을 바꿀 수 있도록 해보자
◽️ 전략 패턴 vs 커맨드 패턴
헤드퍼스트 맨 첫 장에서 전략 패턴에 대해 소개했었다.
일단 둘다 행위 패턴이라는 점에서 비슷하게 느껴지는데 차이점에는 뭐가 있을까?
전략 패턴은 어떻게 동작을 수행하냐에 중점을 두고,
커맨드 패턴은 무엇을 동작하냐에 중점을 둔다.
- 전략 패턴
어떻게?
- 하고자 하는 것은 이미 정해져 있고, 방법을 어떻게 할지에 대한 유연성을 고려하며 구현
- 인터페이스의 메소드에 직접적으로 의존을 하게 되어서, 해당 메소드의 parameter들에 강하게 영향을 받음
- 커맨드 패턴
무엇을?
- 어떻게 할지에 대한 방법은 외부에서 정의하며 주입을 해주며, 그것을 실행하는 것이 중요
- 무엇을 할지를 선택하면 해당 행위를 하기 위한 필요한 변수들을 같이 캡슐화하여 제공받기 때문에 유연하다.
◽️ 장점과 단점
🔎 장점
- 호출자와 수신자의 의존성을 없앨 수 있다.
- 단일 책임 원칙(SIP)에 따라 작업을 수행하는 클래스와 작업을 호출하는 클래스를 분리할 수 있다.
- 개방/폐쇄 원칙(OCP)에 따라 기존 코드를 수정하지 않고 앱에 새로운 명령을 도입할 수 있다.
- 명령의 실행 취소/다시 실행을 구현할 수 있다.
- 지연된 작업 실행을 구현할 수 있다.
🔎 단점
- 호출자와 수신자 사이에 인터페이스를 구현하기 때문에 코드가 복잡해질 수도 있음
참고
야곰닷넷 - 커맨드 패턴
전략패턴과 커맨드패턴