私のソフトウェアエンジニアリングクラスの課題は、特定のゲームでさまざまな形式でプレイできるアプリケーションを設計することです。問題のゲームはMancalaです。これらのゲームのいくつかはWariまたはKalahと呼ばれます。これらのゲームはいくつかの面で異なりますが、私の質問では、ゲームが以下の点で異なる可能性があることを知っておくことが重要です。
- 移動の結果が処理される方法
- ゲームの終了が決定される方法
- 勝者が決定される方法
これを設計するために最初に思いついたのは、戦略パターンを使用することでした。アルゴリズムのバリエーション(ゲームの実際のルール)があります。デザインは次のようになります。
それから私は、マンカラとワリのゲームで勝者が決定される方法はまったく同じであり、コードが複製されるだろうと思いました。これは、定義によって、「1つのルール、1つの場所」またはDRY原則の違反であるとは思わない。マンカラのルールの変更は、Wariのルールも自動的に変更されることを意味しない。それにもかかわらず、教授から得たフィードバックから、私は別のデザインを見つける印象を受けました。
それから私はこれを思いついた:
各ゲーム(Mancala、Wari、Kalahなど)には、各ルールのインターフェイスのタイプの属性があります。つまりWinnerDeterminer
、Mancala 2.0バージョンがあり、Mancala 1.0と同じ場合は、勝者が決定される方法を除きます。 Mancalaバージョンを使用します。
戦略パターンとしてのこれらのルールの実装は確かに有効だと思います。しかし、本当の問題は、さらに設計したいときに起こります。
テンプレートメソッドパターンについて読んで、すぐにこの問題に適用できると思いました。ユーザーが移動したときに実行されるアクションは常に同じであり、同じ順序で、すなわち:
- 穴に石を置く(これはすべてのゲームで同じであるため、テンプレートメソッド自体に実装されます)
- 移動の結果を決定する
- 前の動きのためにゲームが終了したかどうかを判断する
- ゲームが終了したら、誰が勝ったかを判断する
これらの最後の3つの手順は、すべて上記の私の戦略パターンに含まれています。これら2つを組み合わせるのに苦労しています。私が見つけた1つの可能な解決策は、戦略パターンを放棄し、以下を行うことです:
戦略パターンとこれの間のデザインの違いは本当に見られませんか?しかし、テンプレートメソッドを使用する必要があることは確かです(ただし、戦略パターンを使用する必要があることは確かです)。
また、誰がTurnTemplate
オブジェクトの作成を担当するかを判断することもできませんが、戦略パターンでは、抽象的なファクトリパターンを使用して簡単に作成できるオブジェクトのファミリ(3つのルール)があると感じています。私はそれからだろうMancalaRuleFactory
、WariRuleFactory
などと彼らは私がバックアップ規則や手の正しいインスタンスを作成することになりRuleSet
、オブジェクトを。
戦略+抽象ファクトリパターンをRuleSet
使用し、3つのルールのアルゴリズムを持つオブジェクトがあるとします。これでテンプレートメソッドパターンを使用できると感じる唯一の方法は、このRuleSet
オブジェクトをに渡すことTurnTemplate
です。そのとき表面化する「問題」は、の具体的な実装を必要としないことでありTurnTemplate
、これらのクラスは時代遅れになります。の保護されたメソッドでは、TurnTemplate
単に呼び出すことができますruleSet.determineWinner()
。結果として、TurnTemplate
クラスは抽象的ではなくなりますが、具体的になる必要がありますが、それでもテンプレートメソッドパターンですか?
要約すると、私は正しい方法で考えているのですか、それとも簡単な何かを見逃していますか?順調に進んでいる場合、戦略パターンとテンプレートメソッドパターンをどのように組み合わせるのですか?