Java - SubType Enums或SubClass

时间:2014-08-09 13:45:28

标签: java enums

我试图让一个enum对应一个类或返回该类,但我得解决。如果我使用CommandType.SELLSHARES返回SellShares.class,这种行为是否可行?或者,我可以组织具有从父类型继承的不同类别的枚举吗?

命令 - ADMINUSERCLIENT

public enum CommandType {

// SELLSHARES, BUYSHARES, UPDATEUSER, ADDUSER, ADMINASSIGNMENT, BANUSER, CHANGESTATUS, REMOVEUSER

    SELLSHARES (SellShares.class),
    BUYSHARES (BuyShares.class);

    private Class<Command> command;

    CommandType(Class<Command> command) {
        this.command = command;
    }

    private Class<Command> command() { return command; }

    public static <T extends Enum<T>> T getInstance(final String value,
            final Class<T> enumClass) {
        return Enum.valueOf(enumClass, value);
    }

}

OR

public enum CommandType {
    AdminCommands,
    UserCommands
}

enum AdminCommands {
    UPDATEUSER,
    ADDUSER,
    ADMINASSIGNMENT,
    BANUSER,
    CHANGESTATUS,
    REMOVEUSER
}

enum User {
    SELLSHARES,
    BUYSHARES
}

遇到getByType

的问题
void initialCommands() throws Exception
    {
        listCommands = Commands.getByType(Commands.Type.ADMIN);

        for (Commands command : listCommands)
            {
                Command commandss = command.newInstance();
                //addCommand(command.getCommand());
                //log.trace(command.newInstance());

            }

    }

2 个答案:

答案 0 :(得分:0)

你一定在寻找这样的东西:

public enum Commands {

    UPDATE_USER(Type.ADMIN, UpdateUser.class),
    ADD_USER(Type.ADMIN, AddUser.class),
    ADMIN_ASSIGNMENT(Type.ADMIN, AdminAssignment.class),
    BAN_USER(Type.ADMIN, BanUser.class),
    CHANGE_STATUS(Type.ADMIN, ChangeStatus.class),
    REMOVE_USER(Type.ADMIN, RemoveUser.class),

    SELL_SHARES(Type.USER, SellShares.class),
    BUY_SHARES(Type.USER, BuyShares.class);

    public enum Type {
        ADMIN,
        USER;
    }

    public static List<Commands> getByType(Type type) {
        List<Commands> commands = new ArrayList<Commands>();
        for (Commands command : values()) {
            if (command.type.equals(type)) {
                commands.add(command);
            }
        }
        return commands;
    }

    private final Type type;

    private final Class<? extends Command> command;

    private Commands(Type type, Class<? extends Command> command) {
        this.type = type;
        this.command = command;
    }

    public Class<? extends Command> getCommand() {
        return command;
    }

    public Command newInstance() throws Exception {
        return command.newInstance();
    }

}

要创建实例,只需使用:

Commands.UPDATE_USER.newInstance();

获取给定类型的所有命令:

Commands.getByType(Commands.Type.ADMIN);

请注意,使用此方法时,Commands子类必须实现公共的无效构造函数。

答案 1 :(得分:0)

我想提供这个建议和模式。

  • 永远不要在枚举上使用 for/while/loops。
  • 减少在枚举上使用 if-then-else。
  • 但是利用枚举是一个有效的哈希图这一事实。将操作构建到枚举中,这样您就不必迭代枚举来解决由于枚举而导致的操作。
  • 避免使用 if 块来解析枚举的适当操作,而是将函数 lambda 构建到枚举中。
  • 设计您的代码以尽可能多地使用 EnumSet 来“子类化”您的枚举。

重新设计代码流以使用 EnumSet。 不要使用复数但 Command 作为枚举类名称。这样您就可以将命令持有者引用为 Command.ADDUSER 而不是 Commands.ADDUSER。

使用 EnumSet 对枚举中的项进行分类的示例,

enum Command {
    UPDATEUSER,
    ADDUSER,
    ADMINASSIGNMENT,
    BANUSER,
    CHANGESTATUS,
    REMOVEUSER,
    SELLSHARES,
    BUYSHARES,
    ;

    final static public EnumSet<AdminCommands> ADMIN = EnumSet.of(
      UPDATEUSER,
      ADDUSER,
      ADMINASSIGNMENT,
      BANUSER,
      CHANGESTATUS,
      REMOVEUSER
    );

    final static public EnumSet<AdminCommands> USER= EnumSet.of(
      SELLSHARES,
      BUYSHARES
    );
}

构建类构造函数调用,以及它们各自的动作到枚举中:

interface Commander{}
@FunctionalInterface
public interface CommanderNoArg extends Commander {
  Action getAction();
}
@FunctionalInterface
public interface Commander1Arg extends Commander {
  Action getAction(ActionContext ctx);
}
@FunctionalInterface
public interface Commander2Arg extends Commander {
  Action getAction(ActionContext ctx, Options opts);
}

// Auxiliary casters needed due to Java's silly deficient treatment of generics
static private CommanderNoArg hasNoArg(CommanderNoArg lambd) {
  return lambd;
}
static private Commander1Arg has1Arg(Commander1Arg lambd) {
  return lambd;
}
static private Commander2Arg has2Args(Commander2Arg lambd) {
  return lambd;
}


enum Command {
    UPDATEUSER(hasNoArg(UserContext::new) ),
    ADDUSER(hasNoArg(UserContext::new) ),
    ADMINASSIGNMENT(has1Arg(AdminContext::new) ),
    BANUSER(hasNoArg(UserContext::new) ),
    CHANGESTATUS(hasNoNoArg(UserContext::new) ),
    REMOVEUSER(hasNoNoArg(UserContext::new) ),
    SELLSHARES(has2Args(UserContext::new) ),
    BUYSHARES(has2Args(UserContext::new) ),
    ;

    final public Commander commander;
    private Command(Commander cmdr) {
      this.commander = cmdr;
    }

}

因为

  • UserContext 具有不需要参数的构造函数
  • UserContext 也有需要 2 个参数的构造函数
  • AdminContext 的构造函数需要 1 个参数。

例如,您将获得 Action 类

// AdminContext requires 1 argument
Assignment assg = getAssgFromSomewhere();
Action act =
  ((Commander1Arg )Command.ADMINASSIGNMENT.commander)
     .getAction(assg);

或者,您可以将静态方法的 lambda 表达式输入枚举项而不是类。