0Pricing
Java Academy · レッスン

Command パターン:操作のカプセル化

要求を Command オブジェクトとしてラップし、元に戻す・やり直す操作やマクロ記録を実現します。

「Command パターン:操作のカプセル化」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。

Commandの意図

Commandはリクエストをオブジェクトとしてカプセル化し、異なるリクエストによるクライアントのパラメータ化、キューイング、ロギング、取り消し可能な操作を可能にします。

Commandインターフェース

execute()メソッドと、必要に応じてundo()メソッドを持つインターフェースを定義します。各コマンドオブジェクトは、1つのアクションを実行および取り消す方法を把握しています。

public interface Command {
    void execute();
    void undo();
}

具象Command:TextEditor

各具象Commandは、レシーバーとアクションのパラメータをカプセル化します。executeはアクションを実行し、undoはそれを取り消します。

public class InsertTextCommand implements Command {
    private final TextEditor editor;
    private final String text;
    private final int position;
    public InsertTextCommand(TextEditor editor, String text, int pos) {
        this.editor = editor; this.text = text; this.position = pos;
    }
    public void execute() { editor.insert(position, text); }
    public void undo()    { editor.delete(position, text.length()); }
}

Invoker:CommandHistory

Invokerは、実行済みのコマンドの履歴を保持します。execute()を呼び出してスタックにプッシュします。Undoではポップしてundo()を呼び出します。

public class CommandHistory {
    private final Deque<Command> history = new ArrayDeque<>();
    public void execute(Command cmd) {
        cmd.execute();
        history.push(cmd);
    }
    public void undo() {
        if (!history.isEmpty()) history.pop().undo();
    }
}

Undo/Redoスタック

Redoスタックを追加します。UndoするときはRedoスタックにプッシュし、RedoするときはRedoスタックからポップして再実行します。

private final Deque<Command> undoStack = new ArrayDeque<>();
private final Deque<Command> redoStack = new ArrayDeque<>();
public void redo() {
    if (!redoStack.isEmpty()) {
        Command cmd = redoStack.pop();
        cmd.execute();
        undoStack.push(cmd);
    }
}

マクロCommand

マクロCommandはコマンドのリストを保持し、それらを順番に実行するコンポジットです。Undoでは、各操作を取り消す処理を逆順に実行します。

public class MacroCommand implements Command {
    private final List<Command> commands;
    public MacroCommand(List<Command> commands) { this.commands = commands; }
    public void execute() { commands.forEach(Command::execute); }
    public void undo()    { for (int i = commands.size()-1; i>=0; i--) commands.get(i).undo(); }
}

タスク処理用Commandキュー

コマンドをキューに格納し、非同期で処理します。ワーカースレッドがキューから取り出してコマンドを実行するため、生成側と実行スレッドを分離できます。

BlockingQueue<Command> queue = new LinkedBlockingQueue<>();
// Producer:
queue.put(new SendEmailCommand(recipient, subject, body));
// Consumer thread:
Command cmd = queue.take();
cmd.execute();

Executorを使用したCommand

コマンドをRunnableラムダとしてラップし、ExecutorServiceに送信します。このラムダがコマンドオブジェクトになります。

ExecutorService exec = Executors.newFixedThreadPool(4);
exec.submit(() -> sendEmail(recipient, subject));
exec.submit(() -> generateReport(params));

監査用のCommandロギング

SerializableなCommandオブジェクトをログに永続化できます。復旧時にそれらを再生して最終状態を再構築します。これはEvent Sourcingの基盤となります。

void execute(Command cmd) {
    cmd.execute();
    auditLog.append(cmd.toString()); // log every action
    history.push(cmd);
}

GUIアクションボタン

GUIフレームワークでは、各ボタンやメニュー項目がCommandを保持します。ボタンをクリックするとcommand.execute()が呼び出されます。実行時にCommandを入れ替えることで、ボタンの動作を変更できます。

Button saveBtn = new Button("Save");
saveBtn.setOnAction(() -> new SaveDocumentCommand(doc).execute());

CommandとStrategyの比較

どちらも振る舞いをカプセル化します。Strategyは実行時に交換できるアルゴリズムをカプセル化します。Commandはパラメータとレシーバーを含む完全なリクエストをカプセル化し、履歴管理やキューイングをサポートします。

SpringにおけるCommand

Spring BatchのTaskletとSpring IntegrationのMessageHandlerは、アプリケーションレベルのCommandパターンです。各Taskletは、バッチジョブの1つのステップをカプセル化します。

確認問題

Undoをサポートするために、Commandはexecute()以外にどのメソッドを追加しますか。

まとめ

Commandはアクションをオブジェクトとしてカプセル化します。Undo/Redoスタック、タスクキュー、マクロ記録、監査ログに使用します。コマンド履歴を管理するInvokerと組み合わせます。

よくある質問

「Command パターン:操作のカプセル化」レッスンは無料ですか?

はい。「Command パターン:操作のカプセル化」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。

「Command パターン:操作のカプセル化」で何を学びますか?

要求を Command オブジェクトとしてラップし、元に戻す・やり直す操作やマクロ記録を実現します。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Java Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「Command パターン:操作のカプセル化」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このJava Academyレッスンでコードを書いて実行できますか?

はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Observer パターン:イベント通知
  2. Strategy パターン:交換可能なアルゴリズム
  3. Command パターン:操作のカプセル化
  4. Template Method:アルゴリズムの骨格定義
← Java Academyに戻る