커맨드 패턴은 명령을 객체로 캡슐화하여 관리할 수 있게 한다.
커맨드 패턴이 사용되는 상황
- 요청과 수신자의 분리: 커맨드 패턴을 사용하면 요청을 하는 객체(클라이언트)와 실제 작업을 수행하는 객체(수신자)를 분리할 수 있다.
- 연산의 매개변수화: 커맨드 객체를 사용하면 다양한 연산을 하나의 인터페이스를 통해 호출할 수 있다. 각 커맨드는 특정 연산을 수행하며, 이를 인터페이스로 추상화함으로써 클라이언트는 어떤 작업을 수행할지 결정할 수 있다.
- 작업 취소 및 다시 실행(Undo/Redo): 커맨드 패턴을 사용하면 수행된 명령을 저장하고, 나중에 이 명령을 다시 실행하거나 취소할 수 있는 기능을 구현하기에 용이하다. 이는 Undo 및 Redo 기능을 지원하는 애플리케이션에서 유용하다.
- 큐 형태의 명령 처리: 명령을 큐에 저장하고 순서대로 실행할 수 있다. 이를 통해 명령의 처리 순서를 관리하거나, 작업을 비동기적으로 수행할 수 있다.
구성 요소
- Command (명령):명령 인터페이스를 정의하며, execute 메서드를 선언한다.
- ConcreteCommand (구체적인 명령): Command 인터페이스를 구현하는 실제 명령 클래스. 수신자(Receiver) 객체에 대한 호출을 캡슐화한다.
- Client (클라이언트): 명령 객체를 생성하고, 필요한 커맨드를 설정한다.
- Invoker (호출자): 명령 객체를 저장하고, 명령의 실행을 요청하는 역할을 한다.
- Receiver (수신자): 명령에 의해 수행되어야 할 실제 작업을 담당하는 객체.
예제
import java.util.Stack;
// Command interface
interface Command {
void execute();
}
// Receiver
class TextEditor {
private StringBuilder text = new StringBuilder();
private Stack<String> history = new Stack<>();
void addText(String newText) {
history.push(text.toString());
text.append(newText);
System.out.println("텍스트 추가: " + newText);
}
void undo() {
if (!history.isEmpty()) {
text = new StringBuilder(history.pop());
System.out.println("Undo: " + text);
} else {
System.out.println("더 이상 Undo할 내역이 없습니다.");
}
}
void redo() {
if (!history.isEmpty()) {
String redoText = history.pop();
text = new StringBuilder(redoText);
history.push(redoText);
System.out.println("Redo: " + redoText);
} else {
System.out.println("더 이상 Redo할 내역이 없습니다.");
}
}
@Override
public String toString() {
return "TextEditor{" +
"text='" + text + '\'' +
'}';
}
}
// Concrete Command to add text
class AddTextCommand implements Command {
private TextEditor textEditor;
private String text;
AddTextCommand(TextEditor textEditor, String text) {
this.textEditor = textEditor;
this.text = text;
}
@Override
public void execute() {
textEditor.addText(text);
}
}
// Invoker
class TextEditorApp {
private Command command;
void setCommand(Command command) {
this.command = command;
}
void executeCommand() {
command.execute();
}
}
// Main class
public class Main {
public static void main(String[] args) {
// Receiver
TextEditor textEditor = new TextEditor();
// Concrete Commands
Command addText1Command = new AddTextCommand(textEditor, "Hello ");
Command addText2Command = new AddTextCommand(textEditor, "world!");
// Invoker
TextEditorApp textEditorApp = new TextEditorApp();
// Add text
textEditorApp.setCommand(addText1Command);
textEditorApp.executeCommand(); // 텍스트 추가: Hello
textEditorApp.setCommand(addText2Command);
textEditorApp.executeCommand(); // 텍스트 추가: world!
// Undo
textEditor.undo(); // Undo: Hello
// Redo
textEditor.redo(); // Redo: Hello world!
}
}
728x90
'디자인 패턴' 카테고리의 다른 글
Decorator Pattern (0) | 2024.05.05 |
---|---|
Composite Pattern (1) | 2024.05.01 |
Chain Of Responsibility Pattern (0) | 2024.04.27 |
Bridge Pattern (0) | 2024.04.10 |
Adapter Pattern (0) | 2024.04.10 |