
ブログ
不意に10年ぐらい前に書いていたブログを読み返してみると今と全く状況が変わってなくて泣きそうな皆さんこんにちは。

こんなAA描いてた
デザインパターン
と、いうわけでUnity公式から公開されているデザインパターン学習用のサンプルプロジェクトについての記事5回目です。
これまでの記事はこちら
Commandパターン
Commandパターンは、処理の呼び出し側と実装側を分離することを目的としたデザインパターンで、プロダクト内で行う処理を細かい命令(Command)に細分化し、それをそのままオブジェクトとして表現するパターンです。
命令を1つの「オブジェクト」として表現することにより命令の履歴管理を行うことが可能で、それによって命令の訂正、再実行などが容易になります。
例えばレストランでは注文を受けてシェフが料理を作りますが、料理には「肉料理」「魚料理」「野菜料理」等々種類が多様で、それぞれで作業工程、内容が異なります。
しかし、そういった作業内容はシェフ自身が把握していれば良いので、お客側から「鶏肉に小麦粉をまぶして油で揚げて調理して」といった指示を受ける必要はありません。
お客側は「唐揚げ」という料理名を注文するだけで自分が希望する料理が出されるわけです。
こうしたお客(Client)とシェフ(Receiver)間で決められた料理名(Command)で指示→実行を行うパターンがCommandパターンと言えますが、シェフが一人でお客が複数の場合、そのままではシェフがワンオペで複数の料理を同時にこなさなければならず混乱してしまいます。
この為、Commandパターンではお客(Client)とシェフ(Receiver)の間に給仕役(Invoker)を置き、お客からの注文に順序を付けてシェフに料理の依頼を行います。

上の図でいうと伝票がCommandの役割を担っています。伝票は図の通り順番に並べられているため、それが注文履歴となり以後の履歴管理に利用することができます。
サンプルシーン
サンプルプロジェクトの「9 Command」ディレクトリ配下にあるサンプルシーンは以下のよう動作をします。

画面左下にある各方向ボタンをクリックすると「P」のマークの自機がその方向へ移動します。Undo,Redoは実行した命令の訂正、再実行を行います。
Pマークの自機にはPlayerMoverというコンポーネントがアタッチされており、上位から移動方向を指定されるとその方向へ移動する処理が組み込まれています。

このサンプルシーンではボタンクリックのイベントをInputManagerが受け取るとボタンに応じたMoveCommandを生成し、CommandInvokerに対してMoveCommandの実行依頼します。
また、依頼されたMoveCommandはCommandInvoker内でスタック領域に保持されているため、Undoがクリックされた場合、スタック領域から直近のMoveCommandを取り出し(POP)て、そこから逆方向の移動処理を依頼しています。
これらのモジュールの関係を図で表現するとこんな感じになります。

まとめ
Commandパターンは命令を1つの「オブジェクト」として表現するデザインパターンです。
このパターンは処理の呼び出し側と実装側を分離し、命令の履歴管理、Undo/Redoを容易にするという利点があります。
処理のどこからどこまでをコマンド化するのか検討する必要があり、検討が足りないとコードが複雑化する可能性があります。