繁体   English   中英

简化的Java单行验证和分配和返回

[英]Simplified Java one-liner validation and assignment and return

我想简化在方法启动时执行的以下Java 8块:

public void handle(Context ctx) {
    String param = ctx.getParam(name);
    if (!Validation.validate(param)) {
        ctx.markError().end();
        return;
    }
    ... do the same with other params

    ... finally, busines logic on params
}

许多参数都重复这一点。 我希望能够使用Java 8语法更流畅地编写此块,尽可能减少字符。 这里的问题是我们有一个赋值和方法流程中断(返回)。

我在寻找类似的东西:

if (Validator.on(ctx).param("instanceId")) return;

但是,我们在这里错过了一项任务。 我试图使用一些Consumer ,但param必须(有效) final 像(在sudo中 )的东西:

if (Validator.on(ctx).param("instanceId").into(param)) return;
if (Validator.on(ctx).param("instanceId", value -> param = value) return;

(注意ctx.end()包含在里面)。

当然,这不适用于Java。 有任何想法吗?

注意:我控制代码,即此处不使用第三方。

编辑:如果计算机能够理解普通英语,我会说:

验证context参数name ; 如果有效,则将其分配给param ; 如果没有,退出方法。 请 :)

EDIT2 :它不需要是Java 8! 我的意思是,它允许使用Java 8技巧,但它不是强制性的。

这个问题源于忽视早期return只是条件的缩写,例如而不是

if (!Validation.validate(param)) {
    ctx.markError().end();
    return;
}
... business logic on param

你也可以写

if (!Validation.validate(param)) {
    ctx.markError().end();
} else {
... business logic on param
}

因此,您的所有验证框架都需要支持,是一个应该在成功案例中执行的操作,指定为Consumer<String>BiConsumer<Context,String> ,具体取决于是否需要上下文。 然后,用例可能如下所示:

public void handle(Context ctx) {
    Validator.on(ctx).param("instanceId").ifValid( param -> {
        ... business logic on param
    });
}

要么

public void handle(Context ctx) {
    Validator.on(ctx).param("instanceId").ifValid( (context,param) -> {
        ... business logic on param
    });
}

如果需要上下文。 原则上,如果需要上下文,操作可以访问ctx但您可能希望支持以下用例:

public void handle(Context ctx) {
    Validator.on(ctx).param("instanceId").ifValid(this::handleValidated);
}
private void handleValidated(Context ctx, String param) {
    ... business logic on param
}

仅适用于BiConsumer支持。 除此之外,非捕获lambda表达稍微更有效。


既然你已经添加了支持多个参数的想法,那就不再那么简单或简洁了。 一般来说,这个想法可以用于捕获lambda,例如

public void handle(Context ctx) {
    Validator.on(ctx).param("instanceId").ifValid( param ->
    Validator.on(ctx).param("anotherParam").ifValid( param2 ->
    Validator.on(ctx).param("yetOneMore").ifValid( param3 -> {
        ... business logic on param, param2, param3
    })));
}

这可以通过提供预先配置了上下文的验证器作为BiConsumer的参数来BiConsumer

public void handle(Context ctx) {
    Validator.on(ctx).param("instanceId").ifValid( (v,param) ->
        v.param("anotherParam").ifValid( (v,param2) ->
        v.param("yetOneMore").ifValid( (v,param3) -> {
        ... business logic on param, param2, param3
    })));
}

你可以自己决定这是否是一个可行的解决方案......

只需使用辅助函数:

private static boolean check(Context ctx, String value)
{
  if (!Validation.validate(value)) {
    ctx.markError().end();
    return false;
  }
  return true;
}

用法如下所示:

String param = ctx.getParam(name);
if (!check(ctx, param)) return;
/* Assign and test other variables... */
/* Use variables... */

可以为辅助函数提供更多可见性,并根据需要移动到另一个类。

辅助函数可以使用Predicate进行参数化以执行自定义验证,使用Runnable进行自定义故障处理。 (或Consumer ,接受价值或背景;或BiConsumer ,接受价值背景。)

假设您在Stream<String>拥有了所有params的名称,您可以尝试这样的事情:

public void handle(Context ctx) {
    Stream<String> names = Stream.of("name1", "name2", "name3"); // just an example

    if (names.map(Context::getParam).allMatch(Validation::validate)) {
        // business logic here
    } else {
        ctx.markError().end();
    }
}

或者,遵循与您相同的流程样式:

if (!names.map(Context::getParam).allMatch(Validation::validate)) {
    ctx.markError().end();
    return;
}
// business logic here

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM