Friend spotlight!
Whimsical Animations course
Friend spotlight!
NEW Whimsical Animations course
Friend spotlight! NEW Whimsical Animations course
huge discount only this week
Friend spotlight! Want to make your project stand out? NEW Whimsical Animations course huge discount only this week
커맨드

자바로 작성된 커맨드

커맨드는 요청 또는 간단한 작업을 객체로 변환하는 행동 디자인 패턴입니다.

이러한 변환은 명령의 지연 또는 원격 실행, 명령 기록 저장 등을 허용합니다.

복잡도:

인기도:

사용 예시들: 커맨드 패턴은 자바 코드에서 매우 일반적입니다. 대부분의 경우 작업으로 UI 요소를 매개 변수화하기 위한 콜백의 대안으로 사용되며 작업 대기, 작업 기록 추적 등에도 사용됩니다.

다음은 코어 자바 라이브러리로부터 가져온 몇 가지 예시들입니다:

식별: 특정 작업​(예: '복사', '잘라내기', '보내기', '인쇄' 등)​을 나타내는 관련 클래스들의 집합이 존재하는 경우 이는 커맨드 패턴일 수 있습니다. 이러한 클래스들은 같은 인터페이스/추상 클래스를 구현해야 합니다. 커맨드는 자체적으로 관련 작업을 구현하거나 작업을 별도의 객체​(수신자가 될 객체)​에 위임할 수 있습니다. 퍼즐의 마지막 조각은 호출자를 식별하는 것입니다. 자신의 메서드들 또는 생성자들의 매개변수들에서부터 커맨드 객체들을 받는 클래스를 검색하세요.

텍스트 편집기 커맨드들 및 실행 취소

이 예시의 텍스트 편집기는 사용자가 상호 작용할 때마다 새 커맨드 객체를 만듭니다. 작업을 실행한 후 명령이 기록 스택으로 푸시됩니다.

이제 실행 취소 작업을 수행하기 위해 응용 앱은 기록에서 마지막으로 실행된 명령을 가져와 역동작을 수행하거나 해당 명령에 따라 저장된 편집기의 과거 상태를 복원합니다.

commands

commands/Command.java: 추상 기초 커맨드

package refactoring_guru.command.example.commands;

import refactoring_guru.command.example.editor.Editor;

public abstract class Command {
    public Editor editor;
    private String backup;

    Command(Editor editor) {
        this.editor = editor;
    }

    void backup() {
        backup = editor.textField.getText();
    }

    public void undo() {
        editor.textField.setText(backup);
    }

    public abstract boolean execute();
}

commands/CopyCommand.java: 선택한 텍스트를 클립보드에 복사

package refactoring_guru.command.example.commands;

import refactoring_guru.command.example.editor.Editor;

public class CopyCommand extends Command {

    public CopyCommand(Editor editor) {
        super(editor);
    }

    @Override
    public boolean execute() {
        editor.clipboard = editor.textField.getSelectedText();
        return false;
    }
}

commands/PasteCommand.java: 클립보드에서 텍스트 붙여넣기

package refactoring_guru.command.example.commands;

import refactoring_guru.command.example.editor.Editor;

public class PasteCommand extends Command {

    public PasteCommand(Editor editor) {
        super(editor);
    }

    @Override
    public boolean execute() {
        if (editor.clipboard == null || editor.clipboard.isEmpty()) return false;

        backup();
        editor.textField.insert(editor.clipboard, editor.textField.getCaretPosition());
        return true;
    }
}

commands/CutCommand.java: 텍스트를 클립보드로 잘라내기

package refactoring_guru.command.example.commands;

import refactoring_guru.command.example.editor.Editor;

public class CutCommand extends Command {

    public CutCommand(Editor editor) {
        super(editor);
    }

    @Override
    public boolean execute() {
        if (editor.textField.getSelectedText().isEmpty()) return false;

        backup();
        String source = editor.textField.getText();
        editor.clipboard = editor.textField.getSelectedText();
        editor.textField.setText(cutString(source));
        return true;
    }

    private String cutString(String source) {
        String start = source.substring(0, editor.textField.getSelectionStart());
        String end = source.substring(editor.textField.getSelectionEnd());
        return start + end;
    }
}

commands/CommandHistory.java: 커맨드 기록

package refactoring_guru.command.example.commands;

import java.util.Stack;

public class CommandHistory {
    private Stack<Command> history = new Stack<>();

    public void push(Command c) {
        history.push(c);
    }

    public Command pop() {
        return history.pop();
    }

    public boolean isEmpty() { return history.isEmpty(); }
}

editor

editor/Editor.java: 그래픽 사용자 인터페이스 텍스트 편집기

package refactoring_guru.command.example.editor;

import refactoring_guru.command.example.commands.*;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Editor {
    public JTextArea textField;
    public String clipboard;
    private CommandHistory history = new CommandHistory();

    public void init() {
        JFrame frame = new JFrame("Text editor (type & use buttons, Luke!)");
        JPanel content = new JPanel();
        frame.setContentPane(content);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
        textField = new JTextArea();
        textField.setLineWrap(true);
        content.add(textField);
        JPanel buttons = new JPanel(new FlowLayout(FlowLayout.CENTER));
        JButton ctrlC = new JButton("Ctrl+C");
        JButton ctrlX = new JButton("Ctrl+X");
        JButton ctrlV = new JButton("Ctrl+V");
        JButton ctrlZ = new JButton("Ctrl+Z");
        Editor editor = this;
        ctrlC.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                executeCommand(new CopyCommand(editor));
            }
        });
        ctrlX.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                executeCommand(new CutCommand(editor));
            }
        });
        ctrlV.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                executeCommand(new PasteCommand(editor));
            }
        });
        ctrlZ.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                undo();
            }
        });
        buttons.add(ctrlC);
        buttons.add(ctrlX);
        buttons.add(ctrlV);
        buttons.add(ctrlZ);
        content.add(buttons);
        frame.setSize(450, 200);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private void executeCommand(Command command) {
        if (command.execute()) {
            history.push(command);
        }
    }

    private void undo() {
        if (history.isEmpty()) return;

        Command command = history.pop();
        if (command != null) {
            command.undo();
        }
    }
}

Demo.java: 클라이언트 코드

package refactoring_guru.command.example;

import refactoring_guru.command.example.editor.Editor;

public class Demo {
    public static void main(String[] args) {
        Editor editor = new Editor();
        editor.init();
    }
}

OutputDemo.png: 실행 결과

다른 언어로 작성된 커맨드

C#으로 작성된 커맨드 C++로 작성된 커맨드 Go로 작성된 커맨드 PHP로 작성된 커맨드 파이썬으로 작성된 커맨드 루비로 작성된 커맨드 러스트로 작성된 커맨드 스위프트로 작성된 커맨드 타입스크립트로 작성된 커맨드