2015-05-06 159 views
0

我有一個運行遊戲服務器的Socket網絡。爲了簡化相互發送數據,我想使用枚舉作爲構造函數的輸入,並使用基於該枚舉值的構建方法。基於枚舉輸入的返回類

例如,我有一個枚舉:

enum DataType { 
    connectPlayer, 
    returnServerState; 
} 

現在我有一個名爲BuildData構造:

private DataType dataType; 

public BuildData(DataType dataType) { 
    this.dataType = dataType; 
} 

我的問題是:我希望能夠使用的build方法不同基於DataType的輸入。

舉例來說,如果我有數據類型「connectPlayer」,我想構建方法具有以下輸入:

public String build(String UUID, String server) { 
    return "connectPlayer:" + UUID + ":" + server; 
} 

然而,當一個數據類型returnServerState,我希望它是這樣的:

public String build(String thisServer, String serverState) { 
    return "setServerState:" + thisServer + ":" + serverState; 
} 

冒號放置在中間,所以我可以使用拆分方法。

我的問題是:是否必須根據包含正確方法的枚舉類型返回類實例,還是有更簡單的方法來執行此操作?

謝謝!

+0

也許使用您的DataType作爲您的方法的附加參數。 String build(String s1,String s2,DataType dt)' – CubeJockey

+0

您的build()方法是否總是接受相同類型的參數(例如build(String,String))?也就是說,無論DataType如何,構建方法簽名都是相同的? –

+0

對不起@鋼筆粉絲69,忘了提及。不,它有時會根據枚舉類型接受更多參數,有時更少。 – Indy

回答

0

如果所有build方法只是在參數的數目不同,但具有相同的參數類型和相同的返回類型,你可以使用的方法接受varargs,像這樣:

String build(String... args) 

此外,你應該採取請看enum API,因爲java枚舉不僅僅可以枚舉值。

如下您可以擴展您的枚舉:

enum DataType { 
    connectPlayer { 
    @Override 
    public String build(String... args) { 
     if (args.length != 2) throw new IllegalArgumentException("wrong number of arguments"); 
     String UUID = args[0]; 
     String server = args[1]; 
     return "connectPlayer:" + UUID + ":" + server; 
    } 
    }, 
    returnServerState { 
    @Override 
    public String build(String... args) { 
     // do something else here... 
     return "returnServierStateArgs " + Arrays.toString(args); 
    } 
    }; 

    public abstract String build(String... args); 
} 

用法:

System.out.println(DataType.connectPlayer.build("first", "second")); 
System.out.println(DataType.returnServerState.build("first", "second", "...", "more")); 

// prints: 
// connectPlayer:first:second 
// returnServierStateArgs [first, second, ..., more] 

或者,你可以創建一個interface並實施不同的DataType秒。

interface Builder { 
    String build(String... args); 
} 
+0

謝謝大家的幫助!這是我決定使用的解決方案。 – Indy

+0

這基本上是我的答案做得更詳細...幹得好@tomse – m4tt

+0

@ m4tt看起來像我們有同樣的想法... – tomse

0

我的問題是:我必須返回一個基於包含正確方法的枚舉類型的類實例,還是有更簡單的方法來做到這一點?

您無法控制由構造函數實例化的對象的類型。所以你不能在那個時候做出決定。你似乎在尋找的是一個工廠,它會根據你的DataType返回適當的對象。但是,我不認爲這對你有幫助,因爲你需要一個基於類型的不同的build()方法簽名。你需要考慮你沒有以正確的方式處理問題的可能性。具體來說,你想要的是「多樣化地構建()」消息。這是一個討論範圍之外的問題的答案。

+0

如果我正確理解目標,我建議您考慮使用不帶參數的build()(或更好的方法,serialize()或marshall())方法創建一個「Message」接口。該消息應該包含實例變量以及將其序列化到網絡所需的信息。這可以放置在工作人員發送的隊列中。 –

+0

對上述評論進行了一次更正,而不是說「消息應該包含...」我的意思是說,「實現消息接口的類應包含...」 –

0

我會建議做一個工廠,它會根據你的枚舉值給你一個類的實例,並且就返回類型而言,你想返回的所有類類型實例聲明一個將要實現的接口通過你所有的類來使返回類型成爲那個接口。

例如:

Class Factory{ 
    public BaseInterfaceName getInstaceBasedOnEnum(DataType d){ 
     BaseInterfaceName name; 
     switch(d) 
     case q: 
     name = instanceBasedOn D; 
     break; 
    } 
} 

,而其他類的結構要基於數據類型

public class xyz implements BaseInterfaceName; 
public class abc implements BaseInterfaceName; 
+0

不幸的是,他不能這樣做,因爲他需要不同的每種數據類型的方法簽名。 –

+0

他需要根據每個輸入在正確的類中聲明正確的方法,該方法可以在接口中聲明該方法,並將其重載或根據需要重寫該方法。 – piyush

0

我不知道你的架構等來獲得實例,但也許將構建方法放在枚舉類中是很有用的?

public enum DataType { 
CONNECTPLAYER{ 

    @Override 
    public String build(String... strings) { 
     return "connectPlayer:" + strings[0] + ":" + strings[1]; 
    } 

}, 
RETURNSERVERSTATE{ 

    @Override 
    public String build(String... strings) { 
     return "setServerState:" + strings[0] + ":" + strings[1]; 
    } 

}; 

public abstract String build(String...strings); 
} 

如果在enum類中有一個構建方法不是問題,那看起來似乎是一個很好的解決方案。