2015-05-06 125 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类中有一个构建方法不是问题,那看起来似乎是一个很好的解决方案。