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フィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Observer パターン:イベント通知
- Strategy パターン:交換可能なアルゴリズム
- Command パターン:操作のカプセル化
- Template Method:アルゴリズムの骨格定義