Я думаю, что вы должны придерживаться Future[Option[Model]]
именно по причине не бросать и не ловить исключения. Если тип возврата метода равен Option[Model]
, вы не можете пропустить обработку случая отсутствия модели. Подпись типа подсказки может быть ничего невозможен. Вызывающий должен явно указывать map
или fold
за Option
, чтобы избавиться от него и обработать внутреннее устройство Model
.
Поскольку все исключения не отмечены (и проверенные исключения - это просто крушение поезда), компилятор не может намекнуть на то, чтобы вы обрабатывали исключение, поэтому вы можете получить сюрприз во время выполнения. Scala - это скомпилированный и статически типизированный язык, и использование типов для описания возвращаемых данных - довольно чертовски хорошая идея, поскольку компилятор поможет вам все исправить. Это похоже на Ruby! Вы должны понимать преимущества статической типизации и обработки ошибок компиляции.
То же самое относится и к обработке не удалось Future
S: если Future
всегда успешно и не Future
s указует только некоторые неожиданные ошибки, никогда не регулярные вещи, как «модель не найдены», вы можете просто map
над ними без явных проверок, если они» неудачно или нет.
В вашем случае Future[Option[Model]
дает вам лучшую обработку ошибок и управление потоком программ. Если ваш DAO просто выдает исключения, вы получите разбитое приложение с некоторой уродливой трассировкой стека в случае ошибки.Но если ваш DAO возвращает Future[Option[Model]]
, код вызывающего абонента может выглядеть л так:
DAO.findById(id).map { maybeModel: Option[Model] ⇒
maybeModel match {
case Some(model) ⇒ processModel(model)
case None ⇒ exitWithError(s"Could not find model with id = $id")
}
}
(код настолько многословен для целей удобочитаемости)
Приведенный выше код дает вам больший контроль над точками выхода в ваше приложение, которое может быть очень полезно, если ваши требования меняются, и вы не должны разбивать приложение, если модель не найдена. Например, вы можете найти все вызовы exitWithError
и заменить их на logError
или showErrorMessage
вид логики. Это почти невозможно, если вы идете с исключениями.
Другой пример: предположим, что у вас есть 2 метода DAO: findById(id: Long): Future[Option[Model]]
и countById(id: Long): Future[Int]
. Их подписи типов предполагают, что findById
может иметь ничего, чтобы вернуть обратно вызывающему, что указано Option
. countById
всегда должен будет вернуть что-то, которое предлагается просто Int
. При кодировании с помощью этого API вызывающий абонент понимает семантику обоих методов. При вызове findById
они должны думать о двух явных случаях: когда модель найдена, а когда нет. При вызове countById
просто используйте любое возвращаемое значение, всегда Int
.
Надеюсь, что это станет более ясным :) Не стесняйтесь задавать больше вопросов.
Проблема также в том, что обработка Будущего [Option [Mode]] очень сложная, мне нужно написать столько кода, используя карту, а затем совпадение. Я так много делаю в своем приложении, что очень сложно писать простой код. У меня так много для понимания, и для начала каждого из них у меня есть вызов findById. – Blankman
Ну, я мог бы помочь вам, если бы вы поделились некоторыми с вашим кодом. Ваше описание очень расплывчато. Если вы используете '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' Вы можете использовать 'fold', чтобы избежать' match' в 'Option'. –