Nói chung, không có gì sai với API được đề xuất. Nó cung cấp cho bạn chính xác tính linh hoạt mà bạn cần, nhưng yêu cầu bạn phải viết một số lượng soạn sẵn để xử lý kiểu trả về, hoặc sử dụng scalaz/cats và biến đổi đơn điệu để trích xuất mọi thứ.
Nhưng, hãy để tôi thử và đề xuất một API bổ sung.
Hãy xác định đại số của chúng tôi (hoặc các kiểu dữ liệu trừu tượng):
// parten me for the terrible name
sealed trait DomainEntity
case class User(id: UserId) extends DomainEntity
case object EmptyUser extends DomainEntity
case class UserId(id: String)
Thay vì mô hình hóa các phi tồn tại của một người dùng với một Option[A]
, chúng tôi sử dụng đại số của chúng tôi để xác định miền của chúng tôi.
Bây giờ, chúng ta có thể tiếp xúc với một Future[Try[DomainEntity]]
, mà chúng tôi sau này có thể phù hợp cho các kết hợp khác nhau được tạo ra bởi các API:
findUserById(UserId("id")).map {
case Success(user: User) => // Do stuff with user
case Success(EmptyUser) => // We have no user, do something else
case Failure(e) => // Log exception?
}
Nguồn
2016-10-27 12:34:17
Không có gì sai với nó, có bạn có thể có một chút của một loại phức tạp hơn nhưng nó không đại diện cho logic kinh doanh của bạn (tôi cũng có một cái gì đó như thế này), nếu bạn quan tâm đến cách xử lý tốt hơn điều này có một cái nhìn tại 'Disjunction' (thay vì' Either') và 'EitherT' từ scalaz về cách chuyển đổi như một đơn lẻ và chỉ phải đối phó với 'Tùy chọn'. –
Tôi đã viết một dịch vụ web tại nơi làm việc bằng cách sử dụng loại này thường. Có lẽ bạn sẽ tìm thấy [thảo luận] này (https://www.reddit.com/r/scala/comments/3r5ii6/on_handling_futureeithera_b_sequencing/) thú vị. Đặc biệt, tôi hỏi làm thế nào để "chuỗi" tốt hơn trong tương lai [Hoặc [A, B]] '. @tpolecat và những người khác đề nghị sử dụng Monad Transformers, cùng với một ví dụ hữu ích. –