私はScalaとPlay Framework 2.5を使ってWebサービスを開発しています。私のアプリケーションは典型的な階層化アーキテクチャを持っています。私は以下のクラスを持っています:model.User
、repository.UserRepository
、service.UserService
、controllers.UserController
そして私はException
を使わずに経営ロジックエラーを処理する良い方法をしようとしています。スカラのBuisnessロジックエラー処理
次の場合を考慮してください:新規ユーザーの登録要求。要求本体には、email
とpassword
という2つのパラメータがあります。これらのパラメータは、UserService#registerUser
に送られ、電子メールが有効で、そのような電子メールを持つユーザがすでに存在するかどうかがチェックされます。私の解決策はUserService#registerUser
を結果としてEither[BuisnessFailure, Int]
オブジェクトに戻すことです。 BuisnessFailure
は形質であり、WrongEmailFormatFailure
およびUserAlreadyExistFailure
によって継承されています。 電子メールが有効でない場合、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
良い質問ですが、http://softwareengineering.stackexchange.comでより適切になるでしょう – Jubobs
@Jubobsリンクをありがとう。ソフトウェアエンジニアリングについて聞いたことがありません.stackexchange.com。 – alex
私は別のサービスの検証を行いますので、他のサイトを参照するときには、よりテスト可能で再利用可能です –