我想简化在方法启动时执行的以下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。有什么想法吗?
注意:我控制代码,即此处不使用第三方。
编辑:如果计算机能够理解普通英语,我会说:
验证
name
的参数context
;如果有效,请将其分配给param
;如果没有,退出方法。请:)
EDIT2 :它不需要是Java 8!我的意思是,它允许使用Java 8技巧,但它不是强制性的。
答案 0 :(得分:4)
问题源于忽视早期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
的参数来改进:
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
})));
}
你可以自己决定这是否是一个可行的解决方案......
答案 1 :(得分:2)
只需使用辅助功能:
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
,接受价值和背景。)
答案 2 :(得分:1)
假设您在Stream<String>
中拥有了所有参数的名称,您可以尝试这样的事情:
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