2012-04-07 22 views
3

我正在爲作業編寫簡單的紙牌遊戲「戰爭」,現在遊戲正常運行,我試圖讓它更加模塊化和組織化。以下是包含該程序大部分的Main()的一部分。我應該提到,該課程正在用C#教授,但它不是C#課程。相反,我們正在學習基本邏輯和麪向對象的概念,所以我可能不會利用一些C#特性。在Main()中保持模塊性?

bool sameCard = true; 

while (sameCard) 
{ 
    sameCard = false; 
    card1.setVal(random.Next(1,14));  // set card value 
    val1 = determineFace(card1.getVal()); // assign 'face' cards accordingly 
    suit = suitArr[random.Next(0,4)];  // choose suit string from array 
    card1.setSuit(suit);     // set card suit 
    card2.setVal(random.Next(1,14));  // rinse, repeat for card2... 
    val2 = determineFace(card2.getVal());  
    suit = suitArr[random.Next(0,4)];   
    card2.setSuit(suit); 

    // check if same card is drawn twice: 

    catchDuplicate(ref card1, ref card2, ref sameCard); 
} 
Console.WriteLine ("Player: {0} of {1}", val1, card1.getSuit()); 
Console.WriteLine ("Computer: {0} of {1}", val2, card2.getSuit()); 

// compare card values, display winner: 

determineWinner(card1, card2); 

因此,這裏是我的問題:

  • 我可以用在main()循環和仍然認爲它的模塊化?
  • 卡片繪製過程是否寫得很好/包含正確?
  • 在方法中打印信息被認爲是不好的做法(即:determineWinner())?

我只做了兩個學期的編程,我想在這個階段養成良好的習慣。任何意見/建議將不勝感激。

編輯:

catchDuplicate()現在是一個布爾方法和調用如下:

sameCard = catchDuplicate(card1, card2);

感謝@Douglas。

+0

不知道這是否真的是一個StackOverflow問題。這是一種最佳實踐問題,可以是主觀的,但往往會有共識。 – 2012-04-07 20:16:51

+1

'catchDuplicate'是否改變'card1'和'card2'的值?如果沒有,那麼你應該改變它的簽名:'sameCard = catchDuplicate(card1,card2);' – Douglas 2012-04-07 20:17:25

+0

@SionSheevok哦好吧,如果這應該被移動,我會非常樂意。 – nvillec 2012-04-07 20:20:39

回答

3

我可以用在main()循環和仍然認爲這是模塊化?

是的,你可以。但是,OOP程序中的Main通常只包含一些啓動核心功能的方法調用,然後將其存儲在其他類中。

寫得好卡拉絲工藝/載正確?

部分地。如果我正確理解了你的代碼(你只能顯示Main),那麼你會採取一些行動,如果以錯誤的順序或錯誤的值完成,可能不會很好。可以這樣想:如果你賣你的類庫(而不是整個產品,但只有你的類),那麼對於一個外行用戶使用你的庫最清晰的方法是什麼?

I.e.,考慮包含一副牌的類Deck。創建時創建所有卡片並洗牌。給它一個方法Shuffle洗牌甲板,當你的課程的用戶需要洗牌並添加方法如DrawCard處理交易卡。

進一步:你有一些方法不包含在他們自己的類中,但它們的功能在一個類中更好。即,determineFace更適合作爲類別Card(假設card2Card類型)的方法。

在方法中打印消息被認爲是不好的做法(即:determineWinner())?

是,也不是。如果您只想在測試過程中看到消息,請使用Debug.WriteLine。在生產版本中,這些將不可用。但是,當您在生產版本中編寫消息時,請確保此方法的名稱清楚。即,WriteWinnerToConsole什麼的。

這是更常見的而不是這樣做是因爲:你會打印什麼格式的信息?應該附帶哪些文字?你如何處理本地化?但是,在編寫程序時,顯然它必須包含將內容寫入屏幕(或表單或網頁)的方法。這些通常包含在特定的類中。例如,這可以是類CardGameX

總體思路
想想原則「一個方法/函數應該只有一個任務,任務只有一個,它不應該有副作用(如計算平方打印,然後打印副作用)「。

類的原則是非常高級的:一個類包含邏輯上屬於一起並且在同一組屬性/字段上操作的方法。相反的例子:Shuffle不應該是類Card中的方法。但是,它在邏輯上屬於Deck

+1

我很喜歡這個答案。感謝您的明確和詳細的解釋!我目前對OOP的理解程度有限(我的班級剛剛退出程序領域),但這非常有幫助。 – nvillec 2012-04-07 21:13:04

3

如果你的家庭作業的主要問題是創建一個模塊化的應用程序,您必須封裝所有邏輯的專用類。 每個班級只能做一項工作。 玩卡的功能必須在卡類中。 繪製卡片的功能應該是另一個類。

我認爲這是你的功課,好運氣的目標!

+1

通常,在「最佳實踐」-OOP中,每種方法只能完成一項工作。一個類包含一組相關的作業,這些作業使用相同的數據(包含在字段/屬性中)。 – Abel 2012-04-07 20:26:34

+3

+1。是的,基本上'Main'方法只應該實例化一個遊戲類並開始遊戲。像'var game = new CardsGame(); game.Run(); Console.ReadKey();'。 – 2012-04-07 20:27:29

+1

由於問題是**家庭作業**,我們必須嘗試向他展示路徑,不要牽着他的手走路。 現在我看到很多開發者只是現在遵循食譜,而不是編程。 我有希望在這個padawan。 – LawfulHacker 2012-04-07 20:30:38

1

問:我是否可以使用在main()循環和仍然認爲這是模塊化?

答:是的,你可以使用循環,並沒有真正對模塊化的影響。

問:卡片繪製過程是否寫得很好/包含正確?

答:如果你想成爲更加模塊化,轉的drawcard成一個函數/方法。也許只需要寫DrawCards而不是DrawCard,但是那裏有一個優化與模塊化的問題。

問:在方法中打印消息被認爲是不好的做法(即:determineWinner())?

答:我不會說的方法打印的消息是不好的做法,它只是取決於上下文。理想情況下,遊戲本身不處理遊戲邏輯。該程序可以具有某種遊戲對象,並且可以從遊戲對象讀取狀態。這樣,您可以從技術上將遊戲從基於文本的轉變爲圖形。我的意思是,這是模塊化的理想選擇,但在截止日期前可能不太實際。因爲沒有足夠的時間,你總是必須決定何時必須犧牲最佳實踐。可悲的是,這常常是一種常見現象。

從演示文稿中分離出遊戲邏輯。通過這樣一個簡單的遊戲,這是一個不必要的依賴。

+0

+1以獲得詳細解答。感謝您的深入解釋!我有一段時間的'drawCard'方法,它包含了花色和價值分配,併爲每張卡片調用它。但是,理想情況下,每種方法只應對一項任務負責?在哪裏畫線,是「畫一張牌」的一項任務,還是個人的「設置」方法是任務。我想我不明白的是什麼定義了一個單一的任務。 – nvillec 2012-04-07 20:45:42

2

用一點鹽就「最佳做法」採取一切建議。總是爲自己思考。

這就是說:

  • 我可以使用循環在main(),仍然認爲這是模塊化?

這兩個概念是獨立的。如果您的Main()只執行高級邏輯(即調用其他方法),那麼在循環中如果它是這樣做並不重要,畢竟該算法需要循環。 (你會不會增加不必要的循環,不是嗎?)

作爲一個經驗法則,如果可能的話/實用,讓你的程序自文檔。使它「可讀」,如果一個新人(或者甚至你,從現在開始幾個月)看到它,他們可以在任何級別上理解它。

  • 卡片繪製過程寫得好/包含正確嗎?

號首先,卡不應該被選擇兩次。對於更多的「模塊化」的做法我有這樣的事情:

while (Deck.NumCards >= 2) 
{ 
    Card card1 = Deck.GetACard(); 
    Card card2 = Deck.GetACard(); 
    PrintSomeStuffAboutACard(GetWinner(card1, card2)); 
} 
  • 是它認爲不好的做法的方法來打印消息(即:determineWinner())?

determineWinner的用途是打印一條消息嗎?如果答案是「否」,那麼這不是一個「壞習慣」的問題,你的功能是明顯錯誤的。

這就是說,有這樣的事,作爲一個「調試」建設和「釋放」建設。爲了幫助您調試應用程序並確定哪些方法有效,哪些方法無效,添加日誌消息是一個不錯的主意。

確保它們是相關的,並且它們不在「發佈」版本中執行。

+0

感謝您的回答!您對該方法目的的解釋清除了一些事情。我_have_之前添加了日誌記錄消息,以查看程序中發生了什麼,並不知道這是一種實際的做法。 – nvillec 2012-04-07 21:02:54

+1

+1表示「使代碼可讀」。 @nvillec:這些以及許多最佳實踐可以在非常易讀易讀的書中找到[The Pragmatic Programmer](http://www.amazon.com/The-Pragmatic-Programmer-Journeyman-Master/dp/020161622X) 。我可以強烈推薦你的一個里程碑(不要看出版日期,所有內容都適用)。 – Abel 2012-04-08 10:20:12