본문 바로가기

Design/Design Pattern

[Design Pattern] Command Pattern

이번 장에서는 커맨드(Command) 패턴에 대해서 알아본다.
샘플 코드는 여기 (링크) 프로젝트의 테스트 코드로 정리해두었다.


커맨드 패턴이란?
위키백과에 따른 정의는 아래와 같다.

요청을 객체 형태로 캡슐화하여 사용자가 보낸 요청을 나중에 이용할 수 있도록 메서드 이름, 매개변수 등 요청에 필요한 정보를
저장 또는 로깅 취소할 수 있게 하는 패턴.
명령(command), 수신자(receiver), 발동자(invoker), 클라이언트(client)의 네 개의 용어가 따른다.
커맨드 객체는 수신자 객체를 가지고 있으며, 수신자의 메서드를 호출하고 이에 수신자는 자신에게 정의된 메서드를 수행한다.
커맨드는 별도로 발동자 객체에 전달되어 명령을 발동하게 한다. 발동자 객체는 필요에 따라 명령 발동에 대한 기록을 남길 수 있다.

Invoker가 발동자로 설명되어 있지만 정확한 뜻은 호출자다.

어떠한 객체(Receiver)의 기능을 사용할 때 바로 메서드를 호출하는 것이 아니라 명령 객체(Command)를 통해서
캡슐화 되어 있는 메서드를 호출하는 디자인 패턴이다. Receiver와 Invoker사이에 Command 객체를 두어 Receiver와 Invoker간에 의존성을 제거하는데 목적이 있다.

필자는 크롬 브라우저를 통해서 네이버 웹페이지에 접속하는 예시를 들어볼 것이다.
네이버 웹페이지(Receiver)는 자신의 기능들을 캡슐화하고 이를 실행시킬 수 있는 Command 객체만을 제공할 것이다.
이를 호출하는 크롬 브라우저(Invoker)는 사용자(Client)가 어떠한 기능을 원할 때 네이버 웹페이지(Receiver)가 제공한
Command 객체들을 통해 기능들을 실행시킬 것이다.


GoF Design Patterns에 따르면 아래와 같은 Class Diagram이 그려진다.

Command: 실행될 기능들을 명시한 인터페이스.
ConcreteCommand: Command를 구현한 구현체.
Invoker: Command에 명시되어 있는 기능을 호출하는 클래스.
Receiver: 실제로 기능을 수행하는 구현체.

위의 그림으로는 이해가 불가능할 것이다.
이해하기 쉽도록 네이버 웹페이지와 크롬 브라우저를 통해서 Class Diagram을 그려보면 아래와 같은 그림이 그려진다.

네이버 웹페이지(Receiver)는 Chrome Browser(Invoker)가 호출할 수 있도록 NaverCommand를 구현한 커맨드 객체들을 제공한다.
Client들이 네이버 웹페이지의 원하는 기능들을 사용할 때는 ChromeBrowser를 통해서 호출하게 되며 이 때 ChromeBrowser는
네이버 웹페이지에서 제공한 Command 구현체를 통해서 Client가 원하는 기능을 제공하게 된다.


코드를 보면서 하나씩 살펴보도록 한다.

NaverPage Class
Receiver로서 실제로 실행되어야하는 로직들을 캡슐화하여 관리하고 있다.

NaverCommand Abstract Class

NaverCommand의 추상 클래스로서 NaverPage 객체를 가지고 있으며 자신을 확장한 클래스들이 구현해야하는 execute 메서드를 가지고 있다.

MailCommand, NewsCommand, ShoppingCommand, WebToonCommand Class

NaverCommand를 확장(상속)하고 있으며 execute 메서드가 호출될 때 NaverPage의 메서드 중 자신이 호출해야하는 메서드를 호출하고 있다.

ChromeBrowser Class

Command를 호출하는 invoker(호출자)로서 사용자가 Click할 때(click 메서드를 호출할 때) 자신에게 주입된 Command 객체의
execute 메서드를 호출한다.

Client Class

Invoker와 Command를 생성하여 원하는 기능들을 Invoker에 set하여 사용한다.

코드를 실행시킨 결과는 아래와 같다.


지금까지 네이버 웹페이지와 크롬 브라우저를 통해서 커맨드 패턴에 대해서 알아보았다.

여담으로 대부분의 패턴들은 많은 블로그들에 비슷한 내용으로 적혀있다.
하지만 커맨드 패턴은 위키백과부터 시작하여 많은 블로그들에서 서로 다르게 해석하여 적혀있다.
심지어 GoF의 Class Diagram을 보면 마치 Receiver를 통해서 Command를 호출하는 듯하게 그림이 그려져 있어서 상당히 혼란스러웠다.
필자가 이해한 내용을 검증하기 위해 같은 내용의 글을 찾는데 많은 시간을 소비하게 되었다.
필자가 이해한 내용과 정확하게 동일하게 설명한 글이 있어서 많은 도움을 받게되었다.
출처 (링크)를 남긴다.

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

[Design Pattern] Proxy Pattern  (0) 2022.02.06
[Design Pattern] Interpreter Pattern  (0) 2022.02.06
[Design Pattern] Iterator Pattern  (0) 2022.02.04
[Design Pattern] Flyweight Pattern  (0) 2022.02.04
[Design Pattern] Memento Pattern  (0) 2022.02.03