1. 명령 패턴 개요
명령 패턴은 요청을 객체로 캡슐화하여 행위의 분리와 유연성을 달성하는 디자인 패턴입니다. 이 패턴은 작업 기록, 취소, 재실행과 같은 기능이 필요한 시스템에서 특히 효과적입니다.
구조 정의: 명령 인터페이스(Command)는 실행 메서드를 선언합니다. 구체적인 명령(ConcreteCommand)은 이 인터페이스를 구현하며, 수신자(Receiver)를 포함하고 해당 동작을 수행합니다. 수신자는 실제 작업을 처리하는 객체입니다.
역할 및 협업: 주요 구성 요소로 명령(Command), 구체적 명령(ConcreteCommand), 수신자(Receiver), 호출자(Invoker), 클라이언트(Client)가 있습니다. 클라이언트는 명령 객체를 생성하고 수신자를 설정하며, 호출자는 명령을 실행합니다.
적용 사례: 고유연성과 유지보수가 필요한 시스템에 적합합니다. 예로는 메뉴 항목, 작업 취소, 게임 조작 등이 있습니다. 명령 객체를 통해 기존 코드 변경 없이 새로운 기능을 추가할 수 있습니다.
장단점: 장점으로는 모듈화, 확장성, 취소 기능 지원이 있으며, 단점은 명령 객체 수가 많아질 경우 복잡도가 증가합니다.
2. 실무 예제
전화 연결 기능을 구현하는 예제입니다. 다양한 버튼이 다른 소리를 재생하고 최종적으로 연결합니다.
클라이언트 코드
package command;
/**
* 클래스 생성 및 명령 조립 담당
*/
public class PhoneController {
public static void main(String[] args) {
CommandExecutor executor = new CommandExecutor();
PhoneReceiver receiver = new PhoneReceiver();
executor.addCommand(new DigitCommand(1, receiver));
executor.addCommand(new DigitCommand(3, receiver));
executor.addCommand(new DigitCommand(5, receiver));
executor.addCommand(new DigitCommand(3, receiver));
executor.addCommand(new DigitCommand(5, receiver));
executor.addCommand(new DigitCommand(17, receiver));
executor.addCommand(new CallCommand(receiver));
executor.executeCommands();
}
}
명령 실행기
package command;
import java.util.ArrayList;
import java.util.List;
/**
* 명령 실행 관리자
*/
public class CommandExecutor {
private List<Command> commandQueue;
public CommandExecutor() {
commandQueue = new ArrayList<>();
}
public void addCommand(Command command) {
commandQueue.add(command);
}
/**
* 명령 순차 실행, 조합된 작업 처리 가능
*/
public void executeCommands() {
for (Command command : commandQueue) {
command.execute();
}
commandQueue.clear();
}
}
명령 인터페이스
package command;
public interface Command {
void execute();
}
디지털 명령
package command;
/**
* 숫자 버튼 처리
*/
public class DigitCommand implements Command {
private int digit;
private PhoneReceiver receiver;
public DigitCommand(int digit, PhoneReceiver receiver) {
this.digit = digit;
this.receiver = receiver;
}
@Override
public void execute() {
System.out.println("버튼 " + digit + " 소리 재생 및 불빛 켜짐");
receiver.addDigit(digit);
}
}
통화 명령
package command;
/**
* 통화 버튼 처리
*/
public class CallCommand implements Command {
private PhoneReceiver receiver;
public CallCommand(PhoneReceiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.makeCall();
}
}
수신자
package command;
import java.util.ArrayList;
import java.util.List;
/**
* 실제 작업 처리자
*/
public class PhoneReceiver {
// 저장할 전화번호 리스트
private List<Integer> digits;
public PhoneReceiver() {
digits = new ArrayList<>();
}
public void addDigit(int digit) {
System.out.println("입력된 숫자: " + digit);
digits.add(digit);
}
public void makeCall() {
System.out.println("전화 연결 중, 번호: " + digits);
digits.clear();
}
}
실행 결과