我的整個數據庫層目前都爲我的所有模型返回Future [Option [Model]]。爲什麼要在按ID提取時返回Option [Model]?
我發現它只是使期貨工作更加困難,更重要的是我還沒有遇到一個用例,它甚至有意義返回一個選項。
如果模型沒有被Id找到,我的應用程序基本上應該會崩潰。
我不完全確定爲什麼我選擇了[模型],但什麼被認爲是最佳實踐?
我知道在RubyonRails中,當您通過Id(即Model.find(123))獲取它時,如果找不到它,它將引發異常。
我的整個數據庫層目前都爲我的所有模型返回Future [Option [Model]]。爲什麼要在按ID提取時返回Option [Model]?
我發現它只是使期貨工作更加困難,更重要的是我還沒有遇到一個用例,它甚至有意義返回一個選項。
如果模型沒有被Id找到,我的應用程序基本上應該會崩潰。
我不完全確定爲什麼我選擇了[模型],但什麼被認爲是最佳實踐?
我知道在RubyonRails中,當您通過Id(即Model.find(123))獲取它時,如果找不到它,它將引發異常。
在這種情況下我肯定會跟Future[Model]
一起去。即使應用不應該「基本崩潰」,Future
可能會失敗,這可以很容易地處理。使用Future[Option[...]]
,在沒有結果的情況下取得成功是有意義的(例如,在數據庫中存在可空關聯的情況下)。
當您可以使用選項作爲集合時,我發現它非常方便。
這意味着,而不是編寫嵌套的if/else語句來檢查null,然後提取值....您可以將輸出視爲集合並處理它。
這會導致代碼是平坦的,而不是傳統的嵌套if/else方式。
你可以在這裏
http://danielwestheide.com/blog/2012/12/19/the-neophytes-guide-to-scala-part-5-the-option-type.html
閱讀有關使用選項的好處,我想你應該堅持Future[Option[Model]]
正是爲了不扔,而不是捕捉異常的原因。如果方法返回類型爲Option[Model]
,則不能錯過處理模型不在的情況。類型簽名提示可能有沒有什麼可返回的情況。呼叫者必須明確地map
或fold
而不是Option
以擺脫它並且處理內部Model
。由於所有異常都未經檢查(並且檢查的異常僅僅是列車殘骸),因此編譯器無法提示您處理異常,所以您可能會在運行時遇到意外。 Scala是一種編譯和靜態類型的語言,使用類型來描述返回數據是一個非常好的主意,因爲編譯器會幫助你把所有東西都搞定。這在Ruby中是不同的!您必須瞭解靜態類型和編譯與運行時錯誤處理的好處。
同樣適用於處理失敗Future
S:如果Future
始終是成功和失敗的Future
唯一表明一些意外的錯誤,從來沒有像普通的東西「的模式沒有發現」,你可以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
時,他們應該考慮2個明確的情況:何時找到模型和何時不是。當致電countById
時,只需使用返回的任何值,始終爲Int
。
希望這可以讓它更清晰:)隨時提出更多問題。
問題在於,處理Future [Option [Mode]]非常複雜,我必須使用地圖然後匹配編寫這麼多的代碼。我在我的應用程序中這麼做很難編寫簡單的代碼。我有很多理解,每個for-compr的開始都有一個對findById的調用。 – Blankman
好吧,如果你分享了一些你的代碼,我可以幫你。您的描述非常含糊。如果你使用'for'解析,你可能不需要'map'。你可以使用'fold'來避免'選項'上的'匹配'。 –