You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何重构这段Scala代码?基于Play框架优化代码可读性与质量

重构后的Scala + Play框架代码示例

先看重构前的典型混乱代码(模拟你的场景)

package controllers

import play.api.mvc._
import play.api.libs.json._
import scala.concurrent.{ExecutionContext, Future}
import models.User

class UserController @Inject()(val controllerComponents: ControllerComponents)(implicit ec: ExecutionContext) extends BaseController {

  def getUser(id: String) = Action.async { implicit request =>
    // 硬编码错误信息+嵌套逻辑,重复代码多
    if (id.isEmpty) {
      Future.successful(BadRequest(Json.obj("error" -> "User ID cannot be empty")))
    } else {
      User.findById(id).map {
        case Some(user) => Ok(Json.obj(
          "id" -> user.id,
          "name" -> user.name,
          "email" -> user.email,
          "age" -> user.age
        ))
        case None => NotFound(Json.obj("error" -> "User not found with id: " + id))
      }.recover {
        case ex: Exception => InternalServerError(Json.obj("error" -> "Something went wrong: " + ex.getMessage))
      }
    }
  }

  def createUser() = Action.async(parse.json) { implicit request =>
    request.body.validate[User].fold(
      errors => {
        Future.successful(BadRequest(Json.obj("error" -> JsError.toJson(errors))))
      },
      user => {
        if (user.email.isEmpty || user.name.isEmpty) {
          Future.successful(BadRequest(Json.obj("error" -> "Email and name are required")))
        } else {
          User.create(user).map { createdUser =>
            Created(Json.obj(
              "id" -> createdUser.id,
              "name" -> createdUser.name,
              "email" -> createdUser.email,
              "age" -> createdUser.age
            ))
          }.recover {
            case ex: Exception => InternalServerError(Json.obj("error" -> "Failed to create user: " + ex.getMessage))
          }
        }
      }
    )
  }
}

重构后的优雅版本

package controllers

import play.api.mvc._
import play.api.libs.json._
import scala.concurrent.{ExecutionContext, Future}
import models.User

class UserController @Inject()(val controllerComponents: ControllerComponents)(implicit ec: ExecutionContext) extends BaseController {

  // 提取通用JSON格式化器,避免手动拼接JSON
  implicit private val userFormat: OFormat[User] = Json.format[User]

  // 统一错误处理逻辑,减少重复代码
  private def handleServerError(ex: Exception): Result = 
    InternalServerError(Json.obj("error" -> s"Server error: ${ex.getMessage}"))

  // 提取ID参数验证逻辑
  private def validateUserId(id: String): Option[Result] = 
    if (id.isEmpty) Some(BadRequest(Json.obj("error" -> "User ID cannot be empty"))) else None

  def getUser(id: String) = Action.async { implicit request =>
    validateUserId(id)
      .map(Future.successful)
      .getOrElse {
        User.findById(id).map {
          case Some(user) => Ok(Json.toJson(user))
          case None => NotFound(Json.obj("error" -> s"User not found with id: $id"))
        }.recover { case ex => handleServerError(ex) }
      }
  }

  def createUser() = Action.async(parse.json) { implicit request =>
    request.body.validate[User].fold(
      errors => Future.successful(BadRequest(Json.obj("error" -> JsError.toJson(errors)))),
      user => {
        // 用Seq收集所有验证错误,避免嵌套if
        val validationErrors = Seq(
          Option.when(user.name.isEmpty)("Name is required"),
          Option.when(user.email.isEmpty)("Email is required")
        ).flatten

        if (validationErrors.nonEmpty) {
          Future.successful(BadRequest(Json.obj("error" -> validationErrors.mkString(", "))))
        } else {
          User.create(user).map(createdUser => Created(Json.toJson(createdUser)))
            .recover { case ex => handleServerError(ex) }
        }
      }
    )
  }
}

核心优化点

  • 提取重复逻辑:把重复的错误处理、JSON序列化、参数验证抽成独立方法,避免代码冗余
  • 活用Scala特性:用Option.when简化条件判断,字符串插值s""替代拼接,让代码更简洁
  • 统一JSON处理:使用Play自动生成的格式化器Json.format[User],减少手动构建JSON的出错概率
  • 扁平化控制流:用Option.map替代嵌套if-else,让逻辑更线性,降低阅读成本
  • 语义化命名:方法命名比如handleServerError、validateUserId,一眼就能看懂作用

内容的提问来源于stack exchange,提问作者DonDrapper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:59:57