영권's
디자인 패턴(Behavioral) - Command 본문
Command 패턴
명령 패턴은 요청을 요청에 대한 모든 정보를 포함하는 "독립 실행형 개체"로 변환하는 동작 설계 패턴입니다.
예를 들어 클래스가 일을 할때는 자신의 클래스나 다른 클래스의 메서드를 호출합니다.
메서드를 호출한 결과는 객체의 상태에 반영이 되지만, 일의 이력은 남지 않습니다.
이때 '이 일을 실행하시오'라는 '명령'을 표현하는 클래스가 있으면 편리합니다.
실행하고 싶은 일을 '메서드를 호출'하는 동적인 처리로 표현하는 것이 아니라, 명령을 나타내는 클래스의 인스턴스로 하나의 '물건'처럼 표현할 수 있기 때문입니다.
이력을 관리하고 싶을때에는 그 인스턴스의 집합을 관리하면 됩니다.
명령의 집합을 저장해 두면 같은 명령을 재실행할 수도 있고, 또는 복수의 명령을 모아서 새로운 명령으로 재이용할 수도 있습니다.
디자인 패턴에서는 이와 같은 명령을 Command 패턴이라고 합니다.
- Command의 역할
- 명령의 인터페이스(API)를 정의하는 역할입니다.
- 예제 : Command
- ConcreteCommand의 역할
- Command 역할의 인터페이스(API)를 실제로 구현하고 있는 역할입니다.
- 예제 : MacroCommand 클래스와 DrawCommand 클래스
- Receiver의 역할
- Command 역할이 명령을 실행할 때 대상이 되는 역할입니다.
- 명령을 받아들이는 수신자라고 불러도 될 것입니다.
- 예제 : DrawCanvas
- Client의 역할
- ConcreteCommand 역할을 생성하고, 그 사이에 Receiver 역할을 할당합니다.
- 예제 : Main
- Main 클래스는 마우스의 드래그에 맞춰 DrawCommand의 인스턴스를 생성하지만, 그 사이에 Receiver 역할로 DrawCanvas의 인스턴스를 생성자에게 전달
- Invoker의 역할
- 명령의 행동을 개시하는 역할
- Command 역할에서 정의되는 인터페이스(API)를 호출하는 역할이 됩니다.
- 예제 : Main과 DrawCanvas 클래스
- 이 두개의 클래스가 Command 인터페이스의 execute 메서드를 호출하고 있습니다.
장점
- Single Responsibility Principle (단일 책임 원칙)
- 작업을 호출하는 클래스와 이러한 작업을 수행하는 클래스를 분리할 수 있습니다.
- Open/Closed Principle (열림/닫힘 원리)
- 기존 클라이언트 코드를 변경하지 않고 앱에 새 명령을 도입할 수 있습니다.
- 실행 취소/재실행을 구현할 수 있습니다.
- 지연된 작업 실행을 구현할 수 있습니다.
- 간단한 명령 집합을 복잡한 명령 집합으로 조합할 수 있습니다.
단점
- 송신자와 수신자 사이에 완전히 새로운 계층을 도입하기 때문에 코드가 더 복잡해질 수 있습니다.
적용 가능성
- 어떤 작업이 있는 명령을 변수화 하려면 이 패턴을 사용할 수 있습니다.
- 명령 패턴은 특정 메서드 호출을 독립 실행형 개체로 변환할 수 있습니다. 이 변경은 명령을 메서드 인수로 전달하고 다른 개체 내에 저장하며 런타임에 연결된 명령을 전환하는 등 많은 흥미로운 용도를 제공합니다.
다음은 상황에 맞는 메뉴와 같은 GUI 구성 요소를 개발 중이며 최종 사용자가 항목을 클릭할 때 작업을 트리거하는 메뉴 항목을 구성할 수 있도록 하려는 예입니다.
- 명령 패턴은 특정 메서드 호출을 독립 실행형 개체로 변환할 수 있습니다. 이 변경은 명령을 메서드 인수로 전달하고 다른 개체 내에 저장하며 런타임에 연결된 명령을 전환하는 등 많은 흥미로운 용도를 제공합니다.
- 작업을 대기열에 넣거나 실행을 예약하거나 원격으로 실행하려면 명령 패턴을 사용하십시오.
- 다른 개체와 마찬가지로 명령을 직렬화할 수 있습니다.
- 즉, 파일이나 데이터베이스에 쉽게 쓸 수 있는 문자열로 변환합니다.
- 나중에 문자열을 초기 명령 개체로 복원할 수 있습니다.
- 따라서 명령 실행을 지연 및 예약할 수 있습니다.
- 같은 방법으로 네트워크를 통해 명령을 대기열에 넣거나 기록하거나 전송할 수도 있습니다.
- 되돌릴 수 있는 작업을 구현하려는 경우 명령 패턴을 사용합니다.
- 실행 취소/다시 실행을 구현하는 방법에는 여러 가지가 있지만 명령 패턴이 아마도 가장 많이 사용되는 패턴일 것입니다.
- 작업을 되돌리려면 수행한 작업의 기록을 구현해야 합니다. 명령 기록은 응용 프로그램 상태의 관련 백업과 함께 실행된 모든 명령 개체를 포함하는 스택입니다.
- 이 방법에는 두 가지 단점이 있습니다.
- 첫째, 애플리케이션의 일부가 비공개일 수 있기 때문에 애플리케이션의 상태를 저장하는 것이 쉽지 않습니다. 이 문제는 Memento 패턴으로 완화할 수 있습니다.
- 둘째, 상태 백업은 상당히 많은 RAM을 소모할 수 있습니다.
- 그래서 과거 상태를 복원하는 대신 명령이 역연산을 수행합니다. 하지만 구현하기 어렵거나 불가능할 수도 있습니다.
예제 코드)
예시 코드 클래스와 인터페이스 종류
패키지 | 이름 | 해설 |
command.command | Command | '명령'을 표현하는 인터페이스 |
MacroCommand | '복수의 명령을 모은 명령'을 표현하는 클래스 | |
command.drawer | DrawCommand | '점 그리기 명령'을 표현하는 클래스 |
Drawable | '그리기 대상'을 표현하는 인터페이스 | |
DrawCanvas | '그리기 대상'을 구현하는 클래스 | |
command | Main | 동작 테스트용 클래스 |
참고 :
도서) Java언어로 배우는 디자인 패턴 입문
https://refactoring.guru/design-patterns/command
'스터디 > 디자인 패턴' 카테고리의 다른 글
디자인 패턴(Behavioral) - Template Method (0) | 2021.09.02 |
---|---|
디자인 패턴(Behavioral) - Observer (0) | 2021.08.29 |
디자인 패턴(Behavioral) - Memento (0) | 2021.08.20 |
디자인 패턴(Behavioral) - Iterator (0) | 2021.08.13 |
디자인 패턴(Behavioral) - Chain of Responsibility (0) | 2021.08.07 |
Comments