首页 > 解决方案 > 有什么方法可以让代码更干净

问题描述

这是我的代码,这部分我写了两次,如何让代码更干净?

if (res.getNano == 0)
              JString(res.getEpochSecond.toString)
              else
              JString(res.getEpochSecond.toString+ " seconds " +res.getNano.toString + " nanoseconds")

标签: scala

解决方案


我最好的建议是不要在单一范围内做太多事情:制作一次解决一个问题的小功能。并且不要回避分解单行代码并命名中间结果。我知道单行字写起来很愉快,但它们可能会引起读者不必要的不​​安。

在我的编辑中:

  1. 我删除了使用递归来规范化输入以支持第二种方法(在这种情况下是重载,如果您认为有意义,请随意重命名)。
  2. 我将逻辑分解为将 aInstant作为 a渲染为一个JString调用两次的方法。
  3. 我将从 aLocalDateTimeLocalDateto获取的逻辑分解Instant为几个重载方法,以使主逻辑从细节上更加清晰
  4. 我也用camelCase代替snake_case,但这是个人喜好,snake_case如果这是您和您的团队的喜好,请坚持。

我还考虑过让一种方法返回 aTry[JValue]并让第二种方法处理结果,但我认为现在这已经足够了。根据您的上下文评估是否是这种情况。

此外,这里的所有方法都是公开的,因为这是一个简单的纯脚本。我会鼓励你限制可见性,以便只有那些你想暴露的人是(据我所见,我可能只会将原件保留timeToEpoch(params)为公开)。

您可以在 Scastie 上使用此代码。

import java.time.format.DateTimeFormatter
import java.time.{LocalDate, LocalDateTime, ZoneId, ZoneOffset}

import org.json4s._

import scala.util.Try

def timeToEpoch(params: List[JValue]): JValue =
  params match {
    case List(JString(timestamp), JString(pattern)) =>
      timeToEpoch(timestamp, pattern, "UTC")
    case List(JString(timestamp), JString(pattern), JString(timezone)) =>
      timeToEpoch(timestamp, pattern, timezone)
  }

def timeToEpoch(
    timestamp: String,
    pattern: String,
    timeZone: String
): JValue =
  Try {
    val formatter = DateTimeFormatter.ofPattern(pattern)
    val df =
      formatter.parseBest(timestamp, LocalDateTime.from _, LocalDate.from _)
    df match {
      case dateTime: LocalDateTime =>
        formatInstant(toInstant(dateTime), ZoneId.of(timeZone))
      case date: LocalDate =>
        formatInstant(toInstant(date), ZoneId.of(timeZone))
      case _ =>
        JNothing
    }
  }.getOrElse(JNothing)

def toInstant(dateTime: LocalDateTime, timeZone: ZoneId): Instant = {
  val offset = timeZone.getRules.getOffset(LocalDateTime.now)
  val offsetAsString = String.valueOf(offset)
  dateTime.toInstant(offsetAsString)
}

def toInstant(date: LocalDate, timeZone: ZoneId): Instant = {
  date.atStartOfDay(timeZone).toInstant
}

def formatInstant(i: Instant): JString = {
  if (res.getNano == 0)
    JString(s"${res.getEpochSecond}")
  else
    JString(s"${res.getEpochSecond} seconds ${res.getNano} nanoseconds")
}

推荐阅读