【问题标题】:Compacting too many if clauses using Java 8使用 Java 8 压缩太多 if 子句
【发布时间】:2021-06-14 10:23:15
【问题描述】:

我用 Java 编写了以下代码块:

public mainFunction() {

...

if (!functionA(data1, data2)) {
  return new Left<>(Reason.INVALID_RULE);
}

if (!functionB(data1, data2)) {
  return new Left<>(FAILURE.INVALID_ID);
}

 ...there are a few if clauses like above...
}


private boolean functionA(Data1 data1, Data2 data2) {
    if(StringUtils.isNotBlank(data1.getAttr1)) {
       data2.setAttr1(data1.getAttr1);
       return true;
    }
    return false;
}

private boolean functionA(Data1 data1, Data2 data2) {
    try{
       data2.setAttr1(Attr2Enum.fromValue(data1.getAttr1));
       return true;
    } catch (Exception e) {
    return false;
    }
}

现在,我的问题是我可以使用 Java8 压缩它们吗?

【问题讨论】:

  • 不同的函数,不同的返回值,我不确定我们能否让你的代码更简洁。
  • @TimBiegeleisen 返回值和参数实际上在从 mainFunction() 中的 if 子句调用的所有函数中都是相同的。
  • 返回值不同。 (如果它们相同,则不需要调用第二个、第三个等函数。)。但我同意蒂姆的观点,似乎没有任何空间可以让这个更简洁。
  • 你为什么不考虑这个设计的责任链?
  • 不要调用修改传入对象“函数”的操作。不要使用像catch(Exception e) { return false; } 这样的反模式。如果你清理你的代码,问题可能已经消失了。

标签: java java-8 functional-programming


【解决方案1】:

我可以有多种方法来做到这一点。 我尝试创建一个可以进行这种验证链接的验证器接口。 虽然它不是一个完美的解决方案,但它可能会给你一个开始的想法。它是一个非常通用的解决方案(可以使用 ? super 和 ? extends 更通用 - 你可以自己尝试)

代码:

package pecs;

import javafx.util.Pair;

public class Chaining {

    public static void main(String[] args) {
        Validation<Integer, String, Message> validation = (a, b, c) -> {
            return new Pair(a > 30, new Message("a should not be greater than 30"));
        };
        Validation<Integer, String, Message> validation2 = (a, b, c) -> {
            return new Pair(a > 20, new Message("a should not be greater than 20"));
        };
        Validation<Integer, String, Message> validation3 = (a, b, c) -> {
            return new Pair(a > 10, new Message("a should not be greater than 10"));
        };
        Validation<Integer, String, Message> validation4 = (a, b, c) -> {
            return new Pair(a > 5, new Message("a should not be greater than 5"));
        };

        //One way to call
        Validation<Integer, String, Message> validator = validation
                .and(validation2)
                .and(validation3)
                .and(validation4);

        System.out.println(validator.validate(4, "A00", 0));
        System.out.println(validator.validate(9, "A00", 0));
        System.out.println(validator.validate(11, "A00", 0));
        System.out.println(validator.validate(21, "A00", 0));
        System.out.println(validator.validate(31, "A00", 0));

        //Another way to call
        Pair<Boolean, Message> pair = validation
                .and(validation2)
                .and(validation3)
                .and(validation4)
                .validate(4, "String", 0);
        if(pair.getKey() == false) {
            System.out.println("All Validation successful");
        } else {
            System.out.println(pair);
        }

    }
}

代码中使用的验证器接口:

package pecs;

import javafx.util.Pair;
import java.util.Objects;

@FunctionalInterface
public interface Validation<A, B, C> {
    Pair<Boolean, C> validate(A a, B b, int count);

    default Validation<A, B, C> and(Validation<A, B, C> other) {
        Objects.requireNonNull(other);
        return (a, b, c) -> {
//            System.out.println("c=" + c);
            Pair<Boolean, C> validate = validate(a, b, c+1);
            if (validate.getKey() == true) {
                return validate;
            } else {
                //Termination condition.
                if(c == 0) {
                    Pair<Boolean, C> pair = other.validate(a, b, c);
                    if(pair.getKey() == false) {
                        return new Pair<>(false, null);
                    } else {
                        return pair;
                    }
                } else {
                    return other.validate(a, b, c);
                }
            }
        };
    }
}

如果有任何改进,请查看并提出建议。 还有许多其他方法可以进行验证。例如,检查此链接: https://dzone.com/articles/server-side-validator-using-functional-interfaces

【讨论】:

  • 作者从未提及使用 JavaFX,所以请不要让他们导入 JavaFX,因为这会导致几个问题。
  • 是的没错,可以创建自定义配对类
猜你喜欢
  • 2016-04-26
  • 2018-12-30
  • 1970-01-01
  • 2011-12-13
  • 1970-01-01
  • 2019-12-31
  • 2019-05-06
  • 1970-01-01
  • 2014-04-25
相关资源
最近更新 更多