ゲームプロジェクトのクラス図を作成していますが、結合の問題で立ち往生しています。
プロジェクトはターンベースのゲームです。 2人のユーザーが遊んでいます。彼らは地図上にユニットを持っています。それらは、1人のプレイヤーがすべてのユニットを死ぬまで、または事前定義されたターン数に達するまでプレイします。各ラウンドで、各プレイヤーは自分のユニットを1つずつ確認します。
質問に関係のないクラスはカットされました
ゲームクラスは、関連するすべてのオブジェクトを保持します:プレーヤー、ユニット、現在のターン(どのプレーヤーがすでにプレイしたか、次は誰かなど)。 TurnオブジェクトはPlayerTurnオブジェクトを保持します。このオブジェクトは、どのユニットがすでにプレイされているか、どのユニットがプレイされているかを追跡します。
-> GetNextPlayableUnitメソッド(PlayerTurnクラス)を作成しているとしましょう。
現在のプレイヤーのユニットを繰り返し処理し、「PlayedUnits」リストにないユニットを見つける必要があります。したがって、パラメーターGame.Turn.CurrentPlayerを指定してGame.Units.GetUnitsを呼び出す必要があります(Gameは現在のゲームのインスタンスを参照します)。
-> MoveToメソッド(クラスUnit内)を作成しているとしましょう。
ユニットに移動ポイントが残っていない場合は、Game.Turn.PlayerTurn.Finishを呼び出す必要があります。これにより、次のプレイ可能なユニットを選択するか、現在のプレイヤーがこのターンにすべてのユニットをプレイしている場合はそのターンを終了します。
-> ...他のクラスのメソッドにアクセスする必要があるシナリオは他にもたくさんあります。たとえば、ユニットの「キル」メソッドは、現在のプレーヤーがまだ少なくとも1つのユニットを生きているかどうかを確認する必要があり、そうでない場合はゲームのフィニッシュメソッドを呼び出す必要があります。
カップリングは避けられないと思います(間違っていたら訂正してください!)。カップリングを処理する2つの可能な方法について考えました。
これらのクラスのインスタンスを作成するときに、現在のゲームのインスタンスを渡すことができます。結局のところ、それは理にかなっています:ユニットインスタンス、ターンインスタンス、...すべてがゲームに属しています。次に、このインスタンスを使用して、メソッドGetNextPlayableUnit、MoveTo、Killed、...を簡単に実装できます。どういうわけか、依存性注入の原則であることをあちこち読んだとしても、現在のゲームのインスタンスをすべてのモデルクラス間で共有することに不安を感じています。
リスク:
あなたが考えることができる他の解決策はありますか?この特定の場合の最良のアプローチは何でしょうか?
あなたは他の解決策について尋ねます。これらは、解決策を見つけるプロセスを反映している可能性があります。
懸念事項:動作は、同時にいくつかのメソッドUnit.Die()
Playfield.RemoveUnit()
、Player.KillUnit()
で見つけることができます。それは大丈夫です。ただし、コードをコピーしてすべてのメソッドに貼り付けることは避けたいと考えています。
カップリングについて。私はあなたがカップリングを避けない/できる/しなければならない/したくないと思います。一部のオブジェクトは相互作用する必要があります。悪いケースは、すべてのオブジェクトがすべてのメソッドで常に他のすべてのオブジェクトと相互作用する場合です。それは、 関心の分離 のない結合が多すぎます。
そしておそらく時代遅れの意見:OOPはオブジェクトとその相互作用についてであり、クラスについてではなく、継承についてではありません。