编写 checkOrElseThrow 通用函数的更好方法
Better way to write the checkOrElseThrow generic function
我有两个针对 Employee 和 Address DAO 的函数调用 class 我在其中检查员工姓名或地址是否已被使用
为了使检查和抛出异常变得通用,我创建了以下通用函数
checkOrElseThrow 在 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;
}
并且在 EmployeeDAO.java 和 AddressDAO.java 中调用了上述通用函数,如下所示
checkAndReturnEmployee 在 EmployeeDAO.java
public Employee checkAndReturnEmployee(Employee employee) {
return checkOrElseThrow(
employee,
employee.getAddressName(),
() -> new EntityNotFoundException("Employee already in use for another address"));
}
checkAndReturnAddress 在 AddressDAO.java
public Address checkAndReturnAddress(Address address) {
return checkOrElseThrow(
address,
address.getEmployeeName(),
() -> new EntityNotFoundException("Address already in use for another address"));
}
问题
我的解决方案工作正常,但我想知道是否有任何其他更好的方法来重写我编写的通用函数 (checkOrElseThrow)
最好不要这样写。
public Employee checkAndReturnEmployee(Employee employee) {
if (employee.getAddressName() == null) {
throw new EntityNotFoundException("Employee already in use for another address"));
}
return employee;
}
上面的代码同样简短,但更具可读性。更清楚的是什么条件,不满足会怎样。
您的自定义函数仅用于尝试为 Java 创建一种其他人不会理解的新语法,您可能很快也会忘记。
考虑使用 java.util.Optional
,因为您尝试实现的行为已经存在。我发现它比 if (smth != null)
检查要优雅得多。
Optional.ofNullable(employee)
.map(Employee::getAddressName)
.orElseThrow(() -> new EntityNotFoundException("Employee already in use for another address");
总的来说,我更喜欢Optional
,主要是因为如果还需要对entity
进行空检查,人们可能会嵌套多个if
或链接条件(不是这种情况题)。然后你需要像 if (entity != null && entity.getAddress() == null) {throw ...}
这样的东西,它比带 Optional 的链式版本丑陋且可读性差得多。后一种说法,当然也有点句法味道了。
由于问题更多地围绕 通用实现 ,您可以修改现有的实现以利用 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();
}
并在相应的地方进一步调用它:
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"));
}
我有两个针对 Employee 和 Address DAO 的函数调用 class 我在其中检查员工姓名或地址是否已被使用
为了使检查和抛出异常变得通用,我创建了以下通用函数
checkOrElseThrow 在 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;
}
并且在 EmployeeDAO.java 和 AddressDAO.java 中调用了上述通用函数,如下所示
checkAndReturnEmployee 在 EmployeeDAO.java
public Employee checkAndReturnEmployee(Employee employee) {
return checkOrElseThrow(
employee,
employee.getAddressName(),
() -> new EntityNotFoundException("Employee already in use for another address"));
}
checkAndReturnAddress 在 AddressDAO.java
public Address checkAndReturnAddress(Address address) {
return checkOrElseThrow(
address,
address.getEmployeeName(),
() -> new EntityNotFoundException("Address already in use for another address"));
}
问题
我的解决方案工作正常,但我想知道是否有任何其他更好的方法来重写我编写的通用函数 (checkOrElseThrow)
最好不要这样写。
public Employee checkAndReturnEmployee(Employee employee) {
if (employee.getAddressName() == null) {
throw new EntityNotFoundException("Employee already in use for another address"));
}
return employee;
}
上面的代码同样简短,但更具可读性。更清楚的是什么条件,不满足会怎样。
您的自定义函数仅用于尝试为 Java 创建一种其他人不会理解的新语法,您可能很快也会忘记。
考虑使用 java.util.Optional
,因为您尝试实现的行为已经存在。我发现它比 if (smth != null)
检查要优雅得多。
Optional.ofNullable(employee)
.map(Employee::getAddressName)
.orElseThrow(() -> new EntityNotFoundException("Employee already in use for another address");
总的来说,我更喜欢Optional
,主要是因为如果还需要对entity
进行空检查,人们可能会嵌套多个if
或链接条件(不是这种情况题)。然后你需要像 if (entity != null && entity.getAddress() == null) {throw ...}
这样的东西,它比带 Optional 的链式版本丑陋且可读性差得多。后一种说法,当然也有点句法味道了。
由于问题更多地围绕 通用实现 ,您可以修改现有的实现以利用 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();
}
并在相应的地方进一步调用它:
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"));
}