簡體   English   中英

Scala中的商務邏輯錯誤處理

[英]Buisness logic error handling in scala

我正在使用Scala和Play Framework 2.5開發Web服務。 我的應用程序具有典型的分層體系結構。 我有以下類: model.Userrepository.UserRepositoryservice.UserServicecontrollers.UserController ,我正在嘗試一種無需使用Exception即可處理業務邏輯錯誤的好方法。

考慮以下情況:收到了注冊新用戶的請求。 請求正文中有兩個參數: emailpassword 這些參數被饋送到UserService#registerUser ,后者檢查電子郵件是否有效以及使用該電子郵件的用戶是否已經存在。 我的解決方案是使UserService#registerUser返回Either[BuisnessFailure, Int]對象。 BuisnessFailure是一個特征,由WrongEmailFormatFailureUserAlreadyExistFailure繼承。 如果電子郵件無效,則UserService#registerUser返回Left(WrongEmailFormatFailure) 如果已經存在使用此類電子郵件的用戶,則UserService#registerUser返回Left(UserAlreadyExistFailure) 在成功的情況下, UserService#registerUser返回Right(userRepository.create(User(email, password))之后,在controllers.UserController我可以使用模式匹配處理這種情況並發送適當的響應。

那么,這種方法足以應付類似的情況嗎? 請在下面找到我的代碼:

用戶:

package model
case class User(email: String, password: String)

UserRepository:

package repository

import model.User

class UserRepository {
  def create(user: User): Int = ???
  def find(email: String): Option[User] = ???
}

UserService:

package service

import model.User
import repository.UserRepository
import util.{BuisnessFailure, UserAlreadyExistFailure, WrongEmailFormatFailure}

class UserService {
  private val userRepository: UserRepository = ???
  def registerUser(email: String, password: String): Either[BuisnessFailure, Int] = {
    if (userAlreadyExists(email))
      Left(UserAlreadyExistFailure)
    else
      if (!isEmailValid(email))
        Left(WrongEmailFormatFailure)
      else
        Right(userRepository.create(User(email, password)))

  }
  private def isEmailValid(email: String): Boolean = ???
  private def userAlreadyExists(email: String): Boolean = ???
}

UserController的:

package controller

import service.UserService
import util.{UserAlreadyExistFailure, WrongEmailFormatFailure}

class UserController extends play.api.Controller {
  private val userService = new UserService
  def signUp() = Action(parse.json) { implicit request =>
    //obtaining email and password parameters from request body
    val email = ???
    val password = ???
    userService.registerUser(email, password) match {
      case Left(WrongEmailFormatFailure) => // send 400 code and appropriate error message
      case Left(UserAlreadyExistFailure) => // send 400 code and appropriate error message
      case Right(_) => // send response with 200 code
    }
  }
}

BuisnessFailure:

package util

sealed trait BuisnessFailure
case object UserAlreadyExistFailure extends BuisnessFailure
case object WrongEmailFormatFailure extends BuisnessFailure

這正是我們為最大的項目之一進行錯誤處理時所做的事情,而我們沒有任何問題。 Either都應完全那樣使用​​。 Left表示錯誤, Right表示結果。

  • 它是類型安全的
  • 無需擔心並發
  • 該代碼可伸縮且可維護

唯一的一點是,由於大多數Scala應用程序都是非阻塞(異步)應用程序,因此人們將使用Future[Either[Error, Int]]而不是Either[Error, Int] 但是還是可以的,因為每當您決定進行非阻塞時,您都可以輕松地將Either包裝在Future並且正如我告訴您的那樣,無需擔心並發問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM