如何围绕带有动态字段的枚举创建包装类

时间:2019-03-14 09:09:12

标签: java android enums constructor wrapper

我目前正在处理一个android项目,在这里我使用一个枚举来动态创建URL。

根据选择了哪个RequestOperation并将其传递给我的startRequest()方法,将调用另一个API,因此对于映射,我的旧方法是通过切换用例来映射枚举值,并返回相应的url部分为字符串,如下所示:

public enum RequestOperation {

    WORKERS,
    ERRORS_COMPACT,
    ERRORS_COMPLEX,
    ERROR_TAKE_OVER,
    SESSION_CHECK,
    SESSION_LOGIN,
    SESSION_LOGOUT;

    public String parsingKey() {
        switch (this) {
            case WORKERS:
                return "workers";
            case ERRORS_COMPACT:
                return "errors";
            case ERRORS_COMPLEX:
                return "errors";
            case ERROR_TAKE_OVER:
                return "take_over";
            default:
                return "";
        }
    }

    public String apiURL(ArrayList<String> params) {
        switch (this) {
            case WORKERS:
                return "schedule.m";
            case ERRORS_COMPACT:
                return "errors.m?mode=compact";
            case ERRORS_COMPLEX:
                return "errors.m?mode=complex";
            case ERROR_TAKE_OVER:
                return "assign_task.m?param0=" + params.get(0) + "&param1=" + params.get(1);
            case SESSION_CHECK:
                return "desk.m?do=check&param0=" + params.get(0);
            case SESSION_LOGIN:
                return "desk.m?do=login&param0=" + params.get(0) + "&param1=" + params.get(1) + "&param2=" + params.get(2);
            case SESSION_LOGOUT:
                return "desk.m?do=logout&param0=" + params.get(0);
            default:
                return "";
        }
    }

}

如您所见,URL字符串的组成是非常粗糙的编码,对此我没有信心。为了找到一种创建方法,我尝试围绕枚举创建包装类:

public class RequestOperation {

    public enum Type {
        WORKERS("workers", "workers.m"),
        ERRORS_COMPACT("errors", "errors.m?mode=compact"),
        ERRORS_COMPLEX("errors", "errors.m?mode=complex"),

        //here's where im stuck, cause the second string is not the complete url
        ERROR_TAKE_OVER("take_over", "assign_task.m?param0="),
        SESSION_CHECK("", "desk.m?do=check&dparam0="),
        SESSION_LOGIN("", "desk.m?do=login&param0="),
        SESSION_LOGOUT("", "desk.m?do=logout&param0=");

        //maybe pass the params in here some how, and compose the url selectively
        Type(String parsingKey, String applicationUrl) {
            this.parsing_key = parsingKey;
            this.application_url = applicationUrl;
        }

        //maybe move them out of the enum
        private String parsing_key;
        private String application_url;
        //private ArrayList<String> url_params = new ArrayList<>();
    }

    private Type type;

    //expect parameters from the creator here maybe
    public RequestOperation(Type type) {
        this.type = type;
    }

    public String parsingKey() {
        return type.parsing_key;
    }

    public String application_url() {
        return type.application_url;
    }
}

现在我的问题是,我不知道如何将参数传递给RequestOperation对象,以便application_url正确地组成。我的第一个想法是,重载Type的构造函数,因此我最多可以传递3个字符串,这些字符串将像第一个展览中那样填补空白。有什么方法可以解决这个问题吗?

2 个答案:

答案 0 :(得分:2)

我不会在枚举声明中使用诸如?param0=之类的参数,而是将原始网址保留在您的枚举中。

例如,该枚举常量:

 ERROR_TAKE_OVER("take_over", "assign_task.m?param0=")

更改为:

ERROR_TAKE_OVER("take_over", "assign_task.m")

和您的apiURL(String...)可能看起来像这样:

public String apiURL(String... params) {
    if(params.length == 0) return type.application_url;
    return type.application_url 
        + "?" 
        + IntStream.range(0, params.length)
                   .mapToObj(i -> String.format("param%d=%s", i, params[i]))
                   .collect(Collectors.joining("&"));

}

并让webservlet处理可能的参数缺失。

示例:

RequestOperation request = new RequestOperation(RequestOperation.Type.ERROR_TAKE_OVER);
System.out.println(request.apiURL()); //"assign_task.m"
System.out.println(request.apiURL("a")); //"assign_task.m?param0=a"
System.out.println(request.apiURL("a", "b", "c")); //"assign_task.m?param0=a&param1=b&param2=c"

答案 1 :(得分:0)

这可能不是最佳解决方案,而只是解决方法。理想情况下,enum应该存储恒定值,而不是动态值。在您的情况下,解决方法是使用MessageFormat#format()application_url中的enum值将包含占位符为的字符串:

SESSION_LOGIN("", "desk.m?do=login&param0={0}&param1={1}")

请注意使用{}作为占位符。

现在创建一个方法,该方法将根据传递的参数形成URL,如下所示:

public String getApiUrl(String... params) {
    return MessageFormat.format(this.application_url, params);
}

请注意,这是您尝试实现的非常粗略的方法,因为它无法检查可以传递哪些参数或传递多少参数。