Лучший способ написать функцию checkOrElseThrow generi c - PullRequest
2 голосов
/ 05 апреля 2020

У меня есть два вызова функций для класса Employee и Address DAO, где я проверяю, используется ли уже имя или адрес сотрудника.

Для того, чтобы сделать его универсальным c для проверки и выброса исключения, я создал следующее generi c function

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;
}

и вышеупомянутая функция generi c была вызвана в 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 in AddressDAO. java

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

Вопрос

Мое решение - работает нормально, но я хотел бы знать, есть ли другой лучший способ переписать функцию generi c ( checkOrElseThrow ), которую я написал

Ответы [ 3 ]

5 голосов
/ 05 апреля 2020

Лучший способ написать это - нет.

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

Код выше такой же короткий, но гораздо более читаемый. Понятнее, что это за условие, и что происходит, когда оно не выполняется.

Ваша пользовательская функция служит только для попытки создания нового синтаксиса для Java, который другие люди не будут понимать, и вы можете скоро забудем также.

1 голос
/ 05 апреля 2020

Так как вопрос был больше в реализации generi c , вы можете изменить существующую реализацию, чтобы использовать 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"));
}
1 голос
/ 05 апреля 2020

Попробуйте использовать java.util.Optional, поскольку поведение, которого вы пытаетесь достичь, уже существует. Я нахожу это гораздо более элегантным, чем if (smth != null) проверки.

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

В общем, я предпочитаю Optional в основном потому, что можно было бы вложить несколько if с или связать условия, если проверка на ноль для entity также был необходим (не для этого вопроса). Тогда вам понадобится что-то вроде if (entity != null && entity.getAddress() == null) {throw ...}, которое уродливо и гораздо менее читабельно, чем цепная версия с Optional. Последнее утверждение, конечно, также немного напоминает c вкус.

...