0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【デザインパターン】コマンドパターン解説(Flutter / Android 実例付き)

Last updated at Posted at 2025-09-04

1. パターンの意図

コマンド(Command)パターン は、
操作(リクエスト)をオブジェクトとしてカプセル化し、呼び出し元と実行処理を分離する デザインパターンです。

解決する問題

  • 「操作の履歴」「取り消し(Undo)」「やり直し(Redo)」を柔軟に実装したい
  • 呼び出し側(Invoker)と実行側(Receiver)の結合度を下げたい
  • リクエストをキューに貯めて順番に実行したい

ポイント

  • Command:操作を表す抽象インターフェース
  • ConcreteCommand:実際の処理を持つクラス
  • Invoker:Command を実行する(呼び出す)側
  • Receiver:実際の処理を行う対象

2. UML 図


3. Flutter / Dart 実装例

Command インターフェース

abstract class Command {
  void execute();
}

Receiver

class Light {
  void turnOn() => print("Light is ON");
  void turnOff() => print("Light is OFF");
}

ConcreteCommand

class TurnOnCommand implements Command {
  final Light light;
  TurnOnCommand(this.light);

  @override
  void execute() => light.turnOn();
}

class TurnOffCommand implements Command {
  final Light light;
  TurnOffCommand(this.light);

  @override
  void execute() => light.turnOff();
}

Invoker

class RemoteControl {
  Command? _command;

  void setCommand(Command command) {
    _command = command;
  }

  void pressButton() {
    _command?.execute();
  }
}

利用例

void main() {
  var light = Light();
  var remote = RemoteControl();

  remote.setCommand(TurnOnCommand(light));
  remote.pressButton(); // Light is ON

  remote.setCommand(TurnOffCommand(light));
  remote.pressButton(); // Light is OFF
}

4. Android / Kotlin 実装例

Command

interface Command {
    fun execute()
}

Receiver

class Light {
    fun turnOn() = println("Light is ON")
    fun turnOff() = println("Light is OFF")
}

ConcreteCommand

class TurnOnCommand(private val light: Light) : Command {
    override fun execute() = light.turnOn()
}

class TurnOffCommand(private val light: Light) : Command {
    override fun execute() = light.turnOff()
}

Invoker

class RemoteControl {
    private var command: Command? = null

    fun setCommand(command: Command) {
        this.command = command
    }

    fun pressButton() {
        command?.execute()
    }
}

利用例

fun main() {
    val light = Light()
    val remote = RemoteControl()

    remote.setCommand(TurnOnCommand(light))
    remote.pressButton() // Light is ON

    remote.setCommand(TurnOffCommand(light))
    remote.pressButton() // Light is OFF
}

5. 実務ユースケース

Flutter

  • ボタン操作を Command としてカプセル化(Undo/Redo対応)
  • 履歴管理(テキスト編集、UIアクション)
  • Bloc / Redux のアクション設計にも近い

Android (Kotlin)

  • UI ボタン → Command → Receiver(Service/Repository)
  • 操作履歴を保存して Undo/Redo 実装
  • Job キューや WorkManager によるタスク実行

6. メリット / デメリット

メリット

  • 呼び出しと実行を分離 → 疎結合
  • Undo/Redo・履歴管理が容易
  • 複雑な操作キューを柔軟に扱える

デメリット

  • クラス数が増える(CommandごとにConcreteCommandが必要)
  • 小さな処理にはオーバーエンジニアリング

まとめ

  • Command パターンは「リクエストをオブジェクト化して実行を分離」する仕組み
  • Flutter/Android では Undo/Redo、操作履歴、非同期ジョブ実行に便利
  • Strategy が「アルゴリズムを差し替え」なら、Command は「操作を記録して実行」
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?