Возвращать null или Exception?

 
 
 
Сообщения:19
Добрый день!
Читаю Роберта Мартина "Чистый код" и пытаюсь применить советы на практике.

Допустим у меня есть список объектов и есть метод inner(), который проходит по списку и возвращает объект из этого списка, если тот соответствует некоторым параметрам.
Вызывающий метод outer() берет этот объект и кладет в другой список.
Что лучше вернуть из вызываемого метода inner(), если в списке не нашлось подходящего объекта?

1. Вернуть null и в методе outer() делать проверку на null
2. Вернуть специальный объект и в методе outer() делать проверку на него
3. Выбросить checked исключение и в методе outer() оборачивать вызов inner() в try-catch
4. Написать 2 метода. Первый идет по списку и возвращает true если есть такой объект и false если нет. Если первый вернул true, то вызываем второй метод, который опять идет по списку, снова находит объект и возвращает его. Компилятор потребует предусмотреть ситуацию, когда второй метод не нашел объект, тогда можно выбросить unchecked исключение (мы же знаем что он точно найдет)

4-й способ, конечно, позволяет обойтись без проверок и try-catch в методе outer, но двойной проход по списку и костыль в виде выбрасывания unchecked исключения, только чтобы компилятор не ругался очень смущает.

Как же лучше поступить в этом случае?
Спасибо!
Изменен:26 ноя 2020 13:51
 
 
Сообщения:10026
1. Как будто бы самый адекватный из перечисленных. Быстрый, понятный.
2. Нет особого отличия от 1ого кроме того что доп объект какой-то появляется. Есть практика создания Null Objects - однако это больше для того чтоб можно было без доп проверок у такого объекта вызвать метод (а тот ничего не сделает). В то время как null пришлось бы обрабатывать.
3. Слишком сложно для обычного поиска по списку. Особенно учитывая что в Map все-таки null в таких случаях возвращается. Вроде как твой inner() смахивает на мапу. Более того - если проходиться нужно часто, то имеет смысл проиндексировать список по нужному полю Map'кой. Соответственно inner() превращается просто в обращение к этой мапе.
4. Слишком непроизводительный. И проверка кстати остается.
5. Начиная с Java8 есть еще один вариант - возвращение Optional. Также прийдется знать правда что элемента может не быть.. Его удобство больше в том что он явно говорит о том что inner() может ничего не вернуть.
6. Рассматривать inner() как метод фильтрации который возвращает список. outer() будет тогда делать: result.addAll(inner()). Список в твоем случае будет либо пустым либо с одним элементом.

Я бы рассматривал варианты №1, №5 и №6.
Изменен:26 ноя 2020 15:54
 
 
Сообщения:19
Спасибо!
Я и хотел реализовать все по 1-му пункту, но почитав "Чистый код" решил попробовать другие варианты, но сам мало что дельного придумал)
Если делать как в пункте 5, то все равно придется делать проверку isPresent()
Метод inner() в силу некоторых особенностей должен вернуть либо 1 объект либо ни одного. Как вы считаете насколько в этом случае будет оправдана, с точки зрения производительности, такая конструкция как описана в пункте 6 - result.addAll(inner()). Если список возвращенный из inner() будет состоять все время либо из 1 элемента, либо пустой.
 
 
Сообщения:10026
Производительность нужно всегда рассматривать в контексте других проблем. Это валюта которой мы расплачиваемся за все остальное. Если можно сильно упростить код немного пожертвовав производительностью - наверно стоит это сделать. В твоей ситуации лично я добавил бы обычную проверку на null.
Изменен:27 ноя 2020 09:27
 
 
Сообщения:19
Спасибо!
 
 
Сообщения:1552
В случае использования Опшионалов можно написать чистый код используя
ifPresent()
Возвращать налл — это, конечно, быстро, но как-то уж больно олдскульно.

Software and cathedrals are much the same — first we build them, then we pray.
 
 
Сообщения:1057
Optional - мы создаём лишний объект так как не верим, что люди в состоянии(имеют достаточно мозгов чтобы) проверить результат на null.
 
 
Сообщения:1552
Люди пишут на джаве ибо не в состоянии (не имеют достаточно мозгов), чтобы подчистить за собой всю память. И это нормально. 🤷‍♂️

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

Software and cathedrals are much the same — first we build them, then we pray.
 
Модераторы:frymock
Сейчас эту тему просматривают:Нет