Reputation: 214
I have a Socket network running for a game server. To simplify sending data to one another, I want to use enums as input for a constructor and use a build method based on that enum value.
For example, I have an enum:
enum DataType {
connectPlayer,
returnServerState;
}
Now I have a constructor called BuildData:
private DataType dataType;
public BuildData(DataType dataType) {
this.dataType = dataType;
}
My question is: I want to be able to use a build method with different inputs based on the DataType.
For example, if I have DataType 'connectPlayer', I would like a build method with the following inputs:
public String build(String UUID, String server) {
return "connectPlayer:" + UUID + ":" + server;
}
However, when the DataType is returnServerState, I want it to be like this:
public String build(String thisServer, String serverState) {
return "setServerState:" + thisServer + ":" + serverState;
}
The colons are placed inbetween so I can use the split method on them.
My question is: do I have to return a class instance based on the enum type which contains the right method, or is there an easier way to do this?
Thank you!
Upvotes: 0
Views: 3338
Reputation: 501
If all your build
methods just vary in the number of arguments but have the same argument types and the same return type you can use a method accepting varargs, like this:
String build(String... args)
Furthermore you should take a look at the enum API, because java enums can more than just enumerating values.
You could extend your enum as follows:
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);
}
Usage:
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]
Alternatively you could create an interface
and implement it for different DataType
s.
interface Builder {
String build(String... args);
}
Upvotes: 1
Reputation: 102
I don't know your architecture and so on, but maybe it would be useful to put build method inside the enum class like this?
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);
}
If it is not a problem to have a build method inside the enum class, than it seems to be quite a neat solution.
Upvotes: 0
Reputation: 115
I would suggest making a Factory which will give you an instance of the class based on your enum value and as far as return type is concerned, all the types of classes instance you want to return declare a interface which will be implemented by all of your classes so that return type will be that interface.
For Example:
Class Factory{
public BaseInterfaceName getInstaceBasedOnEnum(DataType d){
BaseInterfaceName name;
switch(d)
case q:
name = instanceBasedOn D;
break;
}
}
while structure of other classes for which you want to get the instance based on datatype
public class xyz implements BaseInterfaceName;
public class abc implements BaseInterfaceName;
Upvotes: 0
Reputation: 1039
My question is: do I have to return a class instance based on the enum type which contains the right method, or is there an easier way to do this?
You have no control over the type of object instantiated by a constructor. So you cannot make a decision at that point. What you seem to be looking for is a factory that will return you the appropriate object based on your DataType. However, I don't think that helps you here because you need a different build() method signature based on the type. You need to consider the possibility that you haven't approached the problem in quite the right way. Specifically, it appears that what you want is to "build()" a message polymorphically. That is a discussion that is outside the scope of the answer to this question.
Upvotes: 0