基于枚举输入返回类

时间:2021-08-29 11:55:18

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.

我有一个为游戏服务器运行的Socket网络。为了简化彼此之间的数据发送,我想使用枚举作为构造函数的输入,并使用基于该枚举值的构建方法。

For example, I have an enum:

例如,我有一个枚举:

enum DataType {
    connectPlayer,
    returnServerState;
}

Now I have a constructor called BuildData:

现在我有一个名为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.

我的问题是:我希望能够使用基于DataType的不同输入的构建方法。

For example, if I have DataType 'connectPlayer', I would like a build method with the following inputs:

例如,如果我有DataType'connectPlayer',我想要一个带有以下输入的构建方法:

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

However, when the DataType is returnServerState, I want it to be like this:

但是,当DataType是returnServerState时,我希望它是这样的:

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!

4 个解决方案

#1


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:

如果所有构建方法的参数数量各不相同但参数类型相同且返回类型相同,则可以使用接受varargs的方法,如下所示:

String build(String... args)

Furthermore you should take a look at the enum API, because java enums can more than just enumerating values.

此外,您应该查看枚举API,因为Java枚举不仅可以枚举值。

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 DataTypes.

或者,您可以创建一个接口并为不同的DataType实现它。

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

#2


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.

您无法控制构造函数实例化的对象类型。所以你不能在那时作出决定。您似乎正在寻找的工厂将根据您的DataType返回适当的对象。但是,我认为这对您没有帮助,因为您需要基于类型的不同build()方法签名。你需要考虑你没有以正确的方式解决问题的可能性。具体来说,看起来你想要的是以多态方式“构建()”一条消息。这是一个超出这个问题答案范围的讨论。

#3


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.

我建议创建一个Factory,根据你的枚举值给你一个类的实例,就返回类型而言,你要返回的所有类实例声明一个接口,这个接口将由你的所有实现类,以便返回类型将是该接口。

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;

#4


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?

我不知道你的架构等等,但也许将build方法放在enum类中是有用的吗?

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.

如果在枚举类中有一个构建方法不是问题,那么它似乎是一个非常简洁的解决方案。

#1


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:

如果所有构建方法的参数数量各不相同但参数类型相同且返回类型相同,则可以使用接受varargs的方法,如下所示:

String build(String... args)

Furthermore you should take a look at the enum API, because java enums can more than just enumerating values.

此外,您应该查看枚举API,因为Java枚举不仅可以枚举值。

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 DataTypes.

或者,您可以创建一个接口并为不同的DataType实现它。

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

#2


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.

您无法控制构造函数实例化的对象类型。所以你不能在那时作出决定。您似乎正在寻找的工厂将根据您的DataType返回适当的对象。但是,我认为这对您没有帮助,因为您需要基于类型的不同build()方法签名。你需要考虑你没有以正确的方式解决问题的可能性。具体来说,看起来你想要的是以多态方式“构建()”一条消息。这是一个超出这个问题答案范围的讨论。

#3


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.

我建议创建一个Factory,根据你的枚举值给你一个类的实例,就返回类型而言,你要返回的所有类实例声明一个接口,这个接口将由你的所有实现类,以便返回类型将是该接口。

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;

#4


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?

我不知道你的架构等等,但也许将build方法放在enum类中是有用的吗?

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.

如果在枚举类中有一个构建方法不是问题,那么它似乎是一个非常简洁的解决方案。