简体   繁体   English

编写 checkOrElseThrow 通用 function 的更好方法

[英]Better way to write the checkOrElseThrow generic function

I have two function calls for Employee and Address DAO class where I check if the employee name or address is already in used我有两个 function 调用 Employee 和 Address DAO class 我检查员工姓名或地址是否已被使用

For making it generic to check and throw exception I have created the following generic function为了使其通用检查和抛出异常,我创建了以下通用 function

checkOrElseThrow in CommonUtil.java checkOrElseThrow in CommonUtil.java

public static <R, C, T extends Throwable> R checkOrElseThrow(R rtn, C chk, Supplier<? extends T> ex) throws T
{
    if (chk != null)
    {
        throw ex.get();
    }
    return rtn;
}

and the above generic function is been called in EmployeeDAO.java and AddressDAO.java like as shown below上面的通用 function 在EmployeeDAO.javaAddressDAO.java中被调用,如下所示

checkAndReturnEmployee in EmployeeDAO.java EmployeeDAO.java中的checkAndReturnEmployee

public Employee checkAndReturnEmployee(Employee employee) {
    return checkOrElseThrow(
        employee,
        employee.getAddressName(),
        () -> new EntityNotFoundException("Employee already in use for another address"));
}

checkAndReturnAddress in AddressDAO.java AddressDAO.java中的checkAndReturnAddress

public Address checkAndReturnAddress(Address address) {
    return checkOrElseThrow(
        address,
        address.getEmployeeName(),
        () -> new EntityNotFoundException("Address already in use for another address"));
}

Question问题

My solution is working fine, but I would like to know if there is any other better way to rewrite the generic function ( checkOrElseThrow ) which I have written我的解决方案运行良好,但我想知道是否有任何其他更好的方法来重写我编写的通用 function ( checkOrElseThrow )

The best way to write this is to not.写这个的最好方法是不要。

public Employee checkAndReturnEmployee(Employee employee) {
    if (employee.getAddressName() == null) {
      throw new EntityNotFoundException("Employee already in use for another address"));
    }
    return employee;
}

The code above is just as short, but far more readable.上面的代码同样简短,但更具可读性。 It's clearer what the condition is, and what happens when it is not met.更清楚的是条件是什么,不满足时会发生什么。

Your custom function only serves to attempt to create a new syntax for Java, one that other people will not understand, and you may soon forget also.您的自定义 function 仅用于尝试为 Java 创建一种新语法,其他人不会理解,您可能很快也会忘记。

Consider using java.util.Optional since the behavior that you are trying to achieve is already there.考虑使用java.util.Optional因为您尝试实现的行为已经存在。 I find it far more elegant than if (smth != null) checks.我发现它比if (smth != null)检查要优雅得多。

Optional.ofNullable(employee)
    .map(Employee::getAddressName)
    .orElseThrow(() -> new EntityNotFoundException("Employee already in use for another address");

In general, I prefer Optional mainly because one would probably nest multiple if s or chain the conditions if null check for entity was also needed (not the case for this question).一般来说,我更喜欢Optional主要是因为如果还需要 null 检查entity ,则可能会嵌套多个if或链接条件(不是这个问题的情况)。 Then you would need something like if (entity.= null && entity.getAddress() == null) {throw...} which is ugly and far less readable than the chained version with Optional.然后你需要像if (entity.= null && entity.getAddress() == null) {throw...}这样的东西,它比带有 Optional 的链式版本丑陋且可读性差得多。 The latter statement, of course, is also a bit of syntactic taste.当然,后一种说法也有点句法品味。

Since the question was more around the generic implementation , you could modify your existing implementation to make use of a Predicate to test out any criteria and work it out as:由于问题更多的是围绕通用实现,您可以修改现有实现以使用Predicate来测试任何标准并将其计算为:

public <R, T extends Throwable> R checkOrElseThrow(R returnValue, Predicate<R> successCriteria,
                                                   Supplier<? extends T> ex) throws T {
    if (successCriteria.test(returnValue)) {
        return returnValue;
    }
    throw ex.get();
}

and further invoke this in corresponding places as:并在相应的地方进一步调用它:

public Employee checkAndReturnEmployee(Employee employee) throws EntityNotFoundException {
    return checkOrElseThrow(employee, emp -> emp.getAddressName() != null,
            () -> new EntityNotFoundException("Employee already in use for another address"));
}

public Address checkAndReturnAddress(Address address) throws EntityNotFoundException {
    return checkOrElseThrow(address, add -> add.getEmployeeName() != null,
            () -> new EntityNotFoundException("Address already in use for another address"));
}

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

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