2013-08-11 1 views
3

Скажем, у нас есть метод changeUserName(Long id,String newName), который вызывает findUser(Long id) репозитория, чтобы найти нужный пользовательский объект, а затем изменить его имя.
Уместно ли перекачивать IllegalArgmentException, когда findUser возвращает null?
Или я должен вместо этого добавить пользовательский UserNotExistException (extends AppException extends RuntimeException)?
Должен ли я бросать исключение IllegalArgmentException, когда «пользователь данного идентификатора не существует»?


UPDATE:

  • RuntimeException:
    @nachokk @JunedAhsan На самом деле я сознательно сделать все исключения unchecked, потому что я думаю, что этот способ делает код клиента чистый, легкий для отладки и более безопасный. Что касается этих «необработанных», я поймаю их всех на вершине слоев, избегая показывать их в пользовательском интерфейсе.
    Это связано с тем, что многие клиенты ловят checked exceptions, а затем просто игнорируют его, и в некоторых случаях они не знают, как с ним справиться. Это скрытая проблема.

  • Уточнение:
    Извините за мой плохой английский. Я имел в виду, если changeUserName должен бросить IllegalArgumentException, а не findUser. И еще один вопрос: как отличить illegal argument от business rule violation?

ответ

2

Вы должны использовать UserNotExistException. Имя очень декларативно о том, что происходит. На мой взгляд, вам следует избегать возвращения null, но если вы это сделаете, вам придется документировать его.

UPDATE

Я думал, и как @JunedAhsan предположить, UserNotExistException может быть лучше CheckedException (простирается от Exception, а не RuntimeException).

С этой ссылке: Unchecked Exceptions : Controversy

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

/** 
* @return User found or throw UserNotExistException if is not found 
*/ 
public User findUser(Long id) throws UserNotExistException{ 
    //some code 
    User user = giveMeUserForSomePlace(); 
    if(user == null){ 
     throw new UserNotExistException(); 
    } 
    return user; 
} 
+0

@robjohncox спасибо за перевод на английский xD – nachokk

+0

Не проблема, это не требовало большого перевода :) – robjohncox

+0

Будет ли этот код компилироваться без предложения бросков в определении метода? –

0

Я тоже предлагаю использовать UserNotExistException, но с тем отличием, что вместо того, чтобы он быть непроверенные исключения (в силу расширения RuntimeException), сделать это проверяемое исключение (простирающуюся Exceptionесли AppException не делает это уже).

Это позволит убедиться, что вызывающий абонент changeUserName обрабатывает исключение UserNotExistException и делает код немного надежным.

1

Это зависит от того, как вы обрабатываете исключения.

IllegalArgumentException нормально, если вы показываете только отчет об ошибке с помощью e.getMessage(), и вам не нужен повторяющийся код добавления строки.

Вот некоторые преимущества я нахожу с помощью пользовательских исключений:

1. Снизить reptetive код:

Скажем changeUserName, конечно, не единственный случай, вы будете загружать пользователя, поэтому этот фрагмент кода ниже будет происходить каждый раз, вы вызовете repository.findUser (Long ID)

if (user == null) { 
    throw new IllegalArgumentException("No such user found with given id["+ userId +"]"); 
} 

с другой стороны, одноранговой исключением является гораздо более удобным:

if (user == null) { 
    throw new UserNotExistException(userId); 
} 

public class UserNotExistException extends RuntimeException { 
    public UserNotExistException(Long id) { 
     super("No such user found with given id["+ id +"]"); 
    } 
} 

2. Вам нужно больше поддержки от ваших исключений:

Может быть, вам нужно вернуть код состояния или что-то в этом роде. Специальная инициативная иерафия может помочь:

см. this answer для получения дополнительной информации.

+0

thx @Hippom. В моем проекте я разработал 'UserNotExistException' расширение' AppException', что означает, что он предназначен для «нарушения бизнес-правил». Он отличается от 'changeUserName (-123," Xxx ")' где '-123' является абсолютно незаконным аргументом. Проблема в том, как я могу их различать? – Nozama

+0

@Nozama Почему вы их различаете? Я имею в виду, что ни один из «обычных пользователей не существует» или «бессмысленный -123» невозможен. – Hippoom

+0

Да, они оба не могут быть восстановлены. Но поскольку -123, скорее всего, будет программной ошибкой (возможно, я хочу, чтобы она показывала страницу «500 Internal Error»), тогда как «UserNotExist» может произойти, когда кто-то пытается получить доступ к профилю пользователя «удален» в многопользовательском режиме окружение, и я хочу показать ему «404 Not Found» или что-то, что имеет смысл ... – Nozama

Смежные вопросы