簡體   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