2010-12-01 9 views
0

私はポーカーゲームを正しいOOPモデルに翻訳しようとしています。
基礎:ジェネリッククラスに属性を「埋め込む」ことを避けるには?

class Hand 
{ 
    Card cards[]; 
} 
class Game 
{ 
    Hand hands[]; 
} 

私は、テキストファイルからゲームや手を得ます。私はいくつかの理由で、テキストファイルを複数回解析:

  • GETサムスに関する情報(理由1)
  • は、いくつかの統計(理由2)
  • を計算...

理由1についてクラスハンドにはいくつかの属性(a1、b1)が必要です。理由2のために、私は他の属性(a2、b2)が必要です。私は汚い道は次のようになると思います:

class Hand 
{ 
    Card cards[]; 
    Int a1,b1; 
    Int a2,b2; 
} 

私は、いくつかの属性がほとんど役に立たないことを意味します。だから、 、クリーンであることを、私たちが行うことができます:

class Hand 
{ 
    Card cards[]; 
} 
class HandForReason1 extends Hand 
{ 
    Int a1,b1; 
} 

しかし、私はハンマーを使用してのように感じる...

私の質問は:中間方法はありますか?または、ハンマーの解決策が良いですか? (その場合、正しいセマンティックは何ですか?)

PS:デザインパターン歓迎:-)
PS2:戦略パターンはハンマーですね。ここで

* EDIT * は、アプリケーションです:

// Parse the file, read game infos (reason 1) 
// Hand.a2 is not needed here ! 
class Parser_Infos 
{ 
    Game game; 
    function Parse() 
    { 
      game.hands[0].a1 = ... 
    } 
} 
// Later, parse the file and get some statistics (reason 2) 
// Hand.a1 is not needed here ! 
class Parser_Stats 
{ 
    Game game; 
    function Parse() 
    { 
     game.hand[0].a2 = ... 
    } 
} 
+0

htmlであなたの投稿を書式設定することは多かれ少なかれ動作しますが、Stack Overflowが提供するmarkdownエンジンを使用する方が簡単かつ迅速になります。 [編集ヘルプページ](http://stackoverflow.com/editing-help)。 – dmckee

+0

実際の人生の例をあなたの '属性'に使うと、あなたの問題を把握するのがずっと簡単になると思います。 a1とb1、a2とb2はどういう意味ですか? – Fortega

答えて

0

ポーカーハンドを認識するために責任のチェーンを使用して、私はどうなるのかです。各手はそれ自身の特性を持っているので、あなたは一般的な手を持つことはできません。その後、

abstract class Hand { 
    protected Hand next; 

    abstract protected boolean recognizeImpl(Card cards[]); 

    public Hand setNext(Hand next) { 
     this.next = next; 
     return next; 
    } 

    public boolean Hand recognize(Card cards[]) { 
     boolean result = ; 
     if (recognizeImpl(cards)) { 
     return this; 
     } else if (next != null) { 
     return next.recognize(cards); 
     } else { 
     return null; 
     } 
    } 
} 

ような何かそして、それぞれの手で、それは自分のクラスですが、あなたは初期化することができ、また、あなたのチェーン

// chain start with "best" hand first, we want the best hand 
// to be treated first, least hand last 
Hand handChain = new FullHouse(); 
handChain 
    .setNext(new Triplet()) 
    //.setNext(...)  /* chain method */ 
; 

//... 

Hand bestHand = handChain.recognize(cards); 
if (bestHand != null) { 
    // The given cards correspond best to bestHand 
} 

を構築次に

class FullHouse extends Hand { 
    protected boolean recognizeImpl(Card cards[]) { 
     //... 
    } 
} 
class Triplet extends Hand { 
    protected boolean recognizeImpl(Card cards[]) { 
     //... 
    } 
} 

実装を持っています非常に具体的なものを保持して計算します。しかし、Handクラスを可能な限り多く操作する必要があります(可能な限り多くのオブジェクト指向を維持するために)、ハンドを特定のハンドクラスにキャストする必要はありません。

** UPDATE **

さて、ので、あなたの元の質問(SIG)を答えるためにクラスHandを操作し、 "手" の治療のためです。他の統計やその他のニーズを計算する必要がある場合は、Handクラスをラップすることは良い考えではないかもしれませんが、これは望ましくありません(保守性とOOPパラダイムのため)。

なぜなら、責任の連鎖が示すように、さまざまな種類の手を持つことは問題ありません。あなたはあなたのファイルを読むことができ、必要に応じて多くのパラメータで様々な種類の手を作成することができます。

理由2の理由から、他の解決策を検討することがあります。 1つはあなたのHandクラスにイベントを発し(例:それが認識されたとき)、アプリケーションが他のクラスにそれらのハンドを登録してイベントを待ち受けることができます。その他のクラスは、あなたが読んでいるファイルから必要なデータを収集する責任も負います。手は統計データを収集する責任を負うべきではない(またはそうでなければならない)ので、結論はそれを処理する必要があるということです。

一つのパッケージ =コヒーレントAPIおよび機能

一つのクラス =コヒーレントな機能(手は手ではなく、統計的なコンテナである)(単一)機能を=

一つの方法(メソッドが複数の機能を処理する必要がある場合は、これらの機能を別々のプライベートメソッドに分割し、パブリックメソッドから呼び出す)

私はgivです理由1の理由2は具体的ではないため、ここでは一般的な回答をしています。

+0

あなたの答えをありがとう...しかし、これは私の質問ではないので、私は明らかではないかもしれません:-)私はポーカーハンドを認識しようとしていません、私は属性を "配布"するための最善の方法を得ようとしています。クラス。 Handクラスの属性の中には、統計を計算するために必要なものがあります。その他の属性は他のものに必要です...私はすべての属性を1つのハンドクラスに入れるのはかなり汚いと思います。しかし、継承を使うのは少し重いようです。しかし、これが唯一の方法かもしれません...またはモデルを作成する別の方法がありますか? – Antoine

+0

@Antoine私の答えはあまりにも明確ではありませんでした。より正確な編集をお読みください。 –

+0

私はまだ少し失われていますが、あなたは私に手がかりとルールを与えました。私は非常に手続き型のプログラマー(旧式の学校)であり、時にはどこでもオブジェクトをモデル化するのが難しいと感じることがあります:-) – Antoine

関連する問題