@DennisJaamann が言ったように、コマンドは 1 つのことだけを行う必要があります。ただし、実際のドメイン ロジックを含めることはできません。モデルにもビュークラスにもありません。
理由は次のとおりです。ゲーム ロジックをフレームワーク固有のクラスに配置すると、ゲームはこの 1 つの特定のフレームワークに永久に結び付けられます (たとえそれが優れたものであっても)。ただし、TicTacToe のゲーム ルールは、RobotLegs、PureMVC、またはその他のテクノロジの選択に関係なく、常に同じままにする必要があります。たとえば、数か月以内に新しいモバイル デバイス向けのバージョンのゲームを作成することに決め、ベンダー固有の MVC フレームワークとコンポーネントを使用したい場合、そうでなければすべてを最初からやり直す必要があります。さらに、ゲーム ロジックを複数のコマンド クラスに分散させると、コードの追跡、読み取り、および理解が非常に難しくなります。これにより、デバッグが非常に困難になります。
ボブ・マーティンおじさんが言うように、フレームワークは配信メカニズムです。それ以上でもそれ以下でもありません。情報を配信する、つまりユーザーに提示し、ユーザーの対話イベントを処理するために使用する必要があります。しかし、実際のドメイン ロジックは、逆の依存関係を持つフレームワークに依存しないユース ケース クラスにある必要があるため、配信メカニズムから完全に切り離されます。
したがって、ゲーム インターフェースを作成し、それを単に と呼び、状態 (つまり、どのセルが既にマークされているか) とロジック (つまり、3 つ並んでいるかどうかを確認する) の両方を含むITicTacToe
ゲーム クラスに実装します。 TicTacToe
TicTacToe の 1 ラウンドを実行および監視します。これらは同じ目的で使用され、変更する理由が同じであるため、これらのものは一緒に属しています。
TDD を使用してゲームの動作を実装し、スコアなどを追跡するのではなく、ゲームに勝ったり負けたりするたびにゲーム クラスにイベントをディスパッチさせます。これらはゲームに関するアプリケーション ロジックの一部ですが、ゲーム自体の一部ではありません。
次に、ゲームを に挿入し、CellSelectedCommand
そのコマンドでゲーム クラスの適切なメソッドを呼び出し、ローカル ゲーム イベントがあればリッスンし、中央ディスパッチャーを介してアプリケーション全体のイベントをディスパッチします。GameWonCommand
次に、これらを使用して個別の およびクラスをトリガーGameLostCommand
し、スコアにポイントを追加して に保持することができScoreModel
ます。モデルには、共有状態、つまり複数のタスクで必要とされるデータのみを含める必要があります。大きな棚にある引き出しや箱のようなモデルを考えるのが好きです: タスクを実行するために必要なデータ (つまり、ゲームを開始する前のユーザー情報) を取り出し、それを処理 (プレイ) し、後で保管します。 (スコアを保存します)。
要約すると、経験則は次のとおりです。常に、コア アプリケーション ロジックをフレームワークや配信メカニズムにとらわれないようにしてください。それらは、システムの中心ではなく、必要に応じて拡張機能やプラグインにする必要があります。