2010-12-01 69 views
0

我正在嘗試將撲克遊戲轉換爲正確的OOP模式。
基礎知識:如何避免使用屬性「填充」泛型類?

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

我從一個文本文件,遊戲和手。我分析文本文件幾次,有以下幾個原因:

  • GET薩姆的相關信息(原因1)
  • 計算一些統計數據(原因2)
  • ...

對於原因1我需要Hand類中的一些屬性(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:策略模式是錘子,不是嗎?

*編輯* 下面是一個應用程序:

// 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提供的降價引擎更容易,更快速。 [編輯幫助頁面](http://stackoverflow.com/editing-help)。 – dmckee 2010-12-01 16:09:08

+0

我認爲,如果您爲「屬性」使用真實生活的例子,我們將更容易掌握您的問題。 a1和b1,a2和b2究竟意味着什麼? – Fortega 2010-12-01 16:29:04

回答

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; 
     } 
    } 
} 

,然後讓執行

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

然後建立自己的連鎖

// 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 
} 

而且,每手它自己的類,可以初始化,並有然後保持並計算非常具體的事情。但是,由於您應該儘可能多地操作Hand課程(以儘可能保持OO),因此您應該避免必須將手放在特定的課堂上。

** UPDATE **

好了,所以回答你原來的問題(SIG)類Hand是操作和處理 「手」。如果您需要計算其他統計數據或其他需求,那麼封裝Hand類可能不是一個好主意,因爲您最終將得到一個複合類,這是不可取的(出於可維護性和OOP範式)。

因爲1,擁有不同種類的手是正常的,作爲責任鏈說明;你可以閱讀你的文件,根據需要用許多參數創建不同種類的手。

對於原因2,您可能會看其他解決方案。其中一個就是讓你的Hand類觸發事件(例如,當它被識別時),你的應用程序可以將這些手註冊到其他類中來偵聽事件。其他班級也應該負責從您正在閱讀的文件中收集必要的數據。由於一隻手不是(或者不應該)負責收集統計數據,因此底線是你需要有其他的東西來處理它。

一個包 =相干API和功能

一類 =相干官能團(一個手是手,而不是一個統計容器)

一種方法 =(單個)的功能(如果某個方法需要處理多個功能,請將這些功能分解爲單獨的私有方法,並從公共方法調用它們)

我是giv因爲原因1原因2不是特定的。