본문 바로가기
Design Pattern/행동 패턴(Behavioral Patterns)

커맨드(Command) - 행동 패턴(Behavioral Patterns)

by 김 민 준 2024. 5. 25.

 

커맨드 패턴은 요청을 개체의 형태로 캡슐화 하여 요청에 필요한 모든 정보를 포함시킨다. 이를 통해 큐에 저장하거나 로그로 남기거나 실행 취소 할 수 있는 기능을 제공 할 수 있다. 커맨드 패턴을 사용하면 실행될 기능을 매개변수화 할 수 있으며 요청을 개체로 캡슐화 함으로써 실행할 작업을 독립적으로 관리할 수 있다. 

 

주요 개념 부터 알아보자

 

1. Command 인터페이스 : 실행할 작업을 정의한다. 

2. ConcreateCommand 클래스 : Command 인터페이스를 구현하고, 실제 실행할 작업을 정의 한다.

3. Invoker 클래스 : Command 개체를 실행한다.

4. Receiver 클래스 : 실제로 작업을 수행하는 개체이다.

5. Client 클래스 : Command 개체를 생성하고, Invoker와 Receiver 개체를 설정한다.

 

예시 소스코드로 텍스트 편집기 기능을 구현해보자

 

 

Command Interface

// Command 인터페이스: 실행할 작업을 정의
interface Command {
    void execute();
    void undo();
}

 

Receiver Class 

// TextEditor 클래스: 실제 작업을 수행하는 클래스 (Receiver)
class TextEditor {
    private StringBuilder text = new StringBuilder();

    public void write(String str) {
        text.append(str);
    }

    public void erase(int length) {
        text.delete(text.length() - length, text.length());
    }

    public String getText() {
        return text.toString();
    }
}

 

ConcreteCommand Class 

 

// WriteCommand 클래스: 텍스트 작성 명령
class WriteCommand implements Command {
    private TextEditor editor;
    private String text;

    public WriteCommand(TextEditor editor, String text) {
        this.editor = editor;
        this.text = text;
    }

    @Override
    public void execute() {
        editor.write(text);
    }

    @Override
    public void undo() {
        editor.erase(text.length());
    }
}

 

Invoker Class

 

import java.util.Stack;

// CommandInvoker 클래스: 명령을 실행하고 실행 취소하는 클래스
class CommandInvoker {
    private Stack<Command> commandHistory = new Stack<>();

    public void executeCommand(Command command) {
        command.execute();
        commandHistory.push(command);
    }

    public void undoLastCommand() {
        if (!commandHistory.isEmpty()) {
            Command command = commandHistory.pop();
            command.undo();
        }
    }
}

 

Client Class

 

// Client 클래스: Command 객체를 생성하고 Invoker와 Receiver 객체를 설정
public class CommandPatternDemo {
    public static void main(String[] args) {
        TextEditor editor = new TextEditor();
        CommandInvoker invoker = new CommandInvoker();

        Command writeHello = new WriteCommand(editor, "Hello, ");
        Command writeWorld = new WriteCommand(editor, "world!");

        invoker.executeCommand(writeHello);
        invoker.executeCommand(writeWorld);

        System.out.println("Text after writes: " + editor.getText());

        invoker.undoLastCommand();
        System.out.println("Text after undo: " + editor.getText());

        invoker.undoLastCommand();
        System.out.println("Text after second undo: " + editor.getText());
    }
}

 

출력 

//출력 
//Text after writes: Hello, world!
//Text after undo: Hello, 
//Text after second undo:

 

Command Interface에서 execute와 undo 메서드를 정의했다.

ConcreteCommand Class 에서는 Command 인터페이스를 구현하고, execute와 undo 메서드를 통해 작업을 실행하고 취소한다. 

Invoker Class ㄴ는 명령을 실행하고 실행 취소 할 수 있는 클래스로 명령의 실행과 취소를 관리한다.

Receiver Class 는 실제 작어블 수행하는 클래스이다.

Client Class 는 Command 개체를 생성하고, Invoker와 Receiver 개체를 설정하여 명령을 실행한다.

 

이와같이 실무에서도 실행 취소 기능이나 큐 등으로 활용할때 커맨드 패턴을 사용한다.