2010-05-06 126 views
2

如果有人熟悉Rebecca Wirfs-Brock,她的書中有一段Java代碼,名爲「Object Design:Roles,Responsibilities,and Collaborations」。需要幫助推斷Java代碼

下面是引用>應用雙重分派到具體問題 爲了實現遊戲,石頭,剪刀,我們需要編寫代碼,確定 一個對象是否「擊敗」另一個。根據三種 對象,該遊戲有九種可能的結果。交互次數是各種對象的交叉乘積。大小寫或轉換語句通常由正在操作的數據類型來管理。面向對象的語言等價於將其操作基於其他對象的類。在Java中, 它看起來像這樣 這裏是頁面上的一段Java代碼16 '

import java.util.*;  
    import java.lang.*; 

public class Rock 
{ 
public static void main(String args[]) 
{ 

} 

public static boolean beats(GameObject object) 
{ 
    if (object.getClass.getName().equals("Rock")) 
    { 
     result = false; 
    } 
    else if (object.getClass.getName().equals("Paper")) 
    { 
     result = false;   
    } 
    else if(object.getClass.getName().equals("Scissors")) 
    { 
      result = true; 
    } 
    return result; 
} 

}'

===>這不是一個很好的解決方案。首先,接收者需要知道太多的論點。其次,這三個類中每一個都有一個嵌套的條件語句。如果新的 種類的對象可以被添加到遊戲中,則三個類中的每一個都必須被修改。 任何人都可以與我分享如何讓這個「不到最佳」的代碼片段工作,以便看到它「工作」。她繼續展示一種更好的方式,但我會放過你。 感謝

回答

-2

所以這裏是我如何解決它。我首先創建了一個名爲GameObject的新接口,因爲它們引用它!

public interface GameObject 
{ 
public boolean beats(GameObject g); 
} 

該類型不存在,所以指的是它不會如此偉大。

下面是岩石上的變化我的新代碼註釋:

import java.util.*; 
import java.lang.*; 

public class Rock implements GameObject //Need to be an instance of GameObject somehow! 
{ 
public static void main(String args[]) 
    { 

    } 

public boolean beats(GameObject object) //This isn't static anymore 
{ 
boolean result = false; //Need to declare and initialize result 
if (((Object)object).getClass().getName().equals("Rock")) //getClass should have() 
    { 
    result = false; 
    } 
else if (object.getClass().getName().equals("Paper")) //getClass should have() 
    { 
    result = false; 
    } 
else if(object.getClass().getName().equals("Scissors")) //getClass should have() 
    { 
    result = true; 
    } 
return result; 
} 
} 

編輯:您似乎要詢問如何修復代碼,而不是更好的方式來做到這一點。我相信現在應該很適合你。

+0

好的,謝謝你的改變評論和代碼,這很好。是的,我正試圖修復我的代碼,以配合她在本書第一章中引用的'壞'例子。非常感謝代碼! – dannyrosalex 2010-05-06 18:06:16

+0

爲什麼大家投票呢?這是他正在尋找的東西。如果您對發生了什麼問題有建設性的批評,請發表評論。沒人會說這是解決問題的最好方法,這是他在書中更好的解決方案的一個例子,他無法將它編譯到我所修正的問題上。 – 2010-05-07 16:06:49

1

我個人認爲我只是有一個類似實用程序的類,它將包含'beats'方法。 'beats'方法會將兩個GameObject對象作爲參數。

這樣我就可以傳遞兩個對象(岩石,紙或剪刀)並執行必要的邏輯。現在,如果添加一個新對象,除了實用程序類中的'beats'方法外,您不會更改任何其他內容,而將主要內容封裝起來。

ryan的鏈接很不錯,它也包含處理這種情況的其他幾個想法。

+0

我不認爲主應該放在我放置它的地方。在麗貝卡的書中,這完全不存在。我只是想測試一下。因爲我是Java新手(我是.NET編碼器),所以我應該在另一個文件中找到main?我使用Notepad ++來編輯我的java文件和命令行來編譯 – dannyrosalex 2010-05-06 18:14:31

2

使用enum用於處理它(RPSObj),其具有beats(RPSObj o)方法,用具有Set傳入,存儲爲beatset每個枚舉元素。然後,beats(RPSObj o)方法可以做return beatset.contains(o);。 Simples :)

編輯:實際上,你可以使用一個EnumSet作爲集實現,它應該會比另一組實現更高效的:)

+0

我是一個.NET編程人員,爲了學習良好的對象設計(GOD)而與Java鬼混。我不知道你可以在Enum中定義一個方法。也許我完全無知,但我不知道你可以用這兩種語言做到這一點。 – dannyrosalex 2010-05-06 18:09:29

+0

很好,簡單的解決方案。 – digitaljoel 2010-05-06 18:11:12

+0

@Berlioz你可以看看http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html – 2010-05-06 21:32:34

3

我會定義類RPSSystem和RPSObject開始。構建經典RPS遊戲的代碼是這樣的:

RPSObject rock = new RPSObject("Rock"); 
RPSObject paper = new RPSObject("Paper"); 
RPSObject scissors = new RPSObject("Scissors"); 
RPSSystem classicRPS = new RPSSystem(rock, paper, scissors); 
// new RPSSystem(Collection<RPSObject> objects) possible too 
classicRPS.defineBeatsRule(rock, scissors); 
classicRPS.defineBeatsRule(paper, rock); 
classicRPS.defineBeatsRule(scissors, paper); 

RPSSystem將有一個方法

int fight(RPSObject a, RPSObject b) 

這將返回-1時a勝1時b勝0時結果未定義。內部RPSObjects可以存儲在列表中,並且可以將節拍規則存儲在矩陣中(列和行將與列表中的對象的索引相匹配)。如果應該允許多個類似RPSObject的實例,則應該相應地寫入RPSObject的equals方法。

對系統中的每個對象都有一個單獨的類似乎有點太複雜。

編輯:

完全類:

package rpsgame; 

public final class RPSObject { 
    private final String name; 

    public RPSObject(String name) { 
     this.name = name; 
    } 

    public String getName() { 
     return name; 
    } 

    public String toString() { 
     return getName(); 
    } 
} 

package rpsgame; 

import java.util.Arrays; 
import java.util.Collections; 
import java.util.List; 

public final class RPSSystem { 

    private final List<RPSObject> objects; 
    private final int[][] beatsRules; 

    public static final int WINS = 1; 
    public static final int TIE = 0; 
    public static final int LOSES = -1; 


    public RPSSystem(RPSObject... objects) { 
     this.objects = Arrays.asList(objects.clone()); 
     this.beatsRules = new int[objects.length][objects.length]; 
    } 

    void defineBeatsRule(RPSObject winner, RPSObject loser) { 
     if (winner.equals(loser)) throw new IllegalArgumentException(); 

     int winnerIndex = getObjectIndex(winner); 
     int loserIndex = getObjectIndex(loser); 

     beatsRules[winnerIndex][loserIndex] = WINS; 
     beatsRules[loserIndex][winnerIndex] = LOSES; 
    } 

    public int fight(RPSObject a, RPSObject b) { 
     int aIndex = getObjectIndex(a); 
     int bIndex = getObjectIndex(b); 

     return beatsRules[aIndex][bIndex]; 
    } 

    public List<RPSObject> getObjects() { 
     return Collections.unmodifiableList(objects); 
    } 

    private int getObjectIndex(RPSObject o) { 
     int index = objects.indexOf(o); 
     if (index < 0) throw new IllegalArgumentException(); 
     return index; 
    } 

    // test 
    public static void main(String[] args) { 

     RPSSystem classicRPS = buildClassicRPS(); 

     List<RPSObject> objects = classicRPS.getObjects(); 

     for (RPSObject a: objects) { 
      for (RPSObject b: objects) { 
       int result = classicRPS.fight(a, b); 
       switch (result) { 
        case RPSSystem.WINS: 
         System.out.println(a + " beats " + b); 
         break; 
        case RPSSystem.TIE: 
         System.out.println(a + " vs " + b + " is tied"); 
         break; 
        case RPSSystem.LOSES: 
         System.out.println(a + " loses against " + b); 
         break; 
       } 
      } 
     } 
    } 

    private static RPSSystem buildClassicRPS() { 
     RPSObject rock = new RPSObject("Rock"); 
     RPSObject paper = new RPSObject("Paper"); 
     RPSObject scissors = new RPSObject("Scissors"); 

     RPSSystem classicRPS = new RPSSystem(rock, paper, scissors); 

     classicRPS.defineBeatsRule(rock, scissors); 
     classicRPS.defineBeatsRule(paper, rock); 
     classicRPS.defineBeatsRule(scissors, paper); 
     return classicRPS; 
    } 
} 

只需添加RPSSystem.EVERYONE_DIESdefineEveryoneDiesRule(...),你準備好了

rps.add(atombomb); 
rps.defineBeatsRule(atombomb, scissors); 
rps.defineBeatsRule(atombomb, rock); 
rps.defineBeatsRule(atombomb, paper); 
rps.defineEveryoneDiesRule(atombomb, atombomb); 
+0

謝謝你與我分享你的代碼。 – dannyrosalex 2010-05-06 21:37:41