Должен ли мой класс персистентности возвращать Option или полагаться на исключения? - PullRequest
3 голосов
/ 08 октября 2010

Уровень персистентности моего приложения образован чертой Storage и классом реализации. Я колеблюсь в этом вопросе: методы fetchFoo(key: Key) должны возвращать Option[Foo], или они должны выдавать FooNotFound исключения, если ключ не может быть найден?

Чтобы добавить изюминку в проблему, уровень персистентности - он написан на Scala - вызывается кодом Java. Работа с scala.Option в коде Java? Хммм.

Фактически, до вчерашнего дня уровень персистентности был написан на Java; Я только что переписал это в Scala. Как база кода Java, она основывалась на исключениях, а не возвращала нули; но теперь, когда я столкнулся с scala.Option, я пересматриваю. Мне кажется, что Scala менее очарован исключениями, чем Java.

Ответы [ 3 ]

4 голосов
/ 08 октября 2010

Моя проблема в том, что это зависит от того, откуда приходят ключи.

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

С другой стороны, если ключи поступают из известной системы (это включает в себя такие вещи, как ключи, встроенные в ссылки, которые изначально исходили из системы) и считаются действительными и существуют, я бы оставил их как среду выполнения исключение, обработанное всеобъемлющим на внешнем уровне. Для примера ссылки, если кто-то вручную изменяет ключ в URL-адресе по той или иной причине, его следует рассматривать как неопределенное поведение, и для него подходит исключение, IMO.

Еще один способ думать об этом - как бы вы справились с ситуацией, когда она возникает. Если вы используете Option и просто делегируете случай None какой-то всеобъемлющей обработке ошибок, то, вероятно, более подходящим является исключение. Если вы явно перехватываете исключение NotFound и изменяете поток программы (например, запрашиваете у пользователя повторный ввод ключа), тогда используйте Option, или проверенное исключение (или Either в Scala), чтобы убедиться, что Ситуация разбирается.

Что касается интеграции с Java, Option достаточно прост в использовании, когда библиотека времени выполнения Scala доступна на пути к классам. Кроме того, в библиотеке Functional Java есть реализация Option. В любом случае, я бы воздержался от использования null для обозначения «не найдено».

2 голосов
/ 08 октября 2010

В Java вы можете вызывать опции isEmpty, isDefined и get без особых хлопот (действительно полезные методы Option, такие как getOrElse, это другой вопрос.) Проверка результата isDefined метод в условии if должен быть быстрее, чем проверка исключений в блоке try-catch.

0 голосов
/ 08 октября 2010

В некоторых случаях (например, в вашем примере) опция Option - это хорошо, а «монадическое» поведение (map, flatMap, filter ...) очень удобно, но в других случаях вам нужна дополнительная информация о причине проблемы, которая может быть лучше выраженным с исключением. Теперь вы, вероятно, хотите, чтобы обработка ошибок была как можно более «равномерной», поэтому я бы предложил использовать Either , что дает вам как поведение, подобное Option, так и выразительность как исключение.

В Java вам нужна только вспомогательная функция, которая "распаковывает" Either. Если он находит Right (значение), он возвращает значение, если он находит Left (исключение), он перебрасывает его. После этого вы вернетесь к нормальному поведению Java.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...