简化的 Java 单行验证和赋值以及 return
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 语法更流畅地编写这个块,尽可能少的字符。这里的问题是我们有一个分配和方法流中断(return)。
我在寻找类似的东西:
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 中不起作用。有什么想法吗?
注意:我控制代码,即这里没有使用第 3 方。
编辑:如果计算机能够理解简单的英语,我会说:
Validate parameter name
of context
; if it is valid, assign it to a param
; if not, exit the method. Please :)
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
:
的参数来改进
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
})));
}
你可以自己决定这是否是一个可行的解决方案......
假设您在 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
只需使用辅助函数:
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... */
辅助函数可以被赋予更多可见性,并酌情移至另一个 class。
可以使用 Predicate
参数化辅助函数以执行自定义验证,并使用 Runnable
参数化以执行自定义故障处理。 (或 Consumer
,接受值或上下文;或 BiConsumer
,接受值 和 上下文。)
我想简化以下 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 语法更流畅地编写这个块,尽可能少的字符。这里的问题是我们有一个分配和方法流中断(return)。
我在寻找类似的东西:
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 中不起作用。有什么想法吗?
注意:我控制代码,即这里没有使用第 3 方。
编辑:如果计算机能够理解简单的英语,我会说:
Validate parameter
name
ofcontext
; if it is valid, assign it to aparam
; if not, exit the method. Please :)
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
:
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
})));
}
你可以自己决定这是否是一个可行的解决方案......
假设您在 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
只需使用辅助函数:
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... */
辅助函数可以被赋予更多可见性,并酌情移至另一个 class。
可以使用 Predicate
参数化辅助函数以执行自定义验证,并使用 Runnable
参数化以执行自定义故障处理。 (或 Consumer
,接受值或上下文;或 BiConsumer
,接受值 和 上下文。)