有什么方法可以使代码更清晰

时间:2020-05-04 05:00:44

标签: scala

这是我的代码,我写了两次,如何使代码更简洁?

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

1 个答案:

答案 0 :(得分:3)

我的最佳建议是不要在一个范围内做太多事情:创建一些小的功能,一次解决一个问题。并且不要回避打破一线而命名中间结果。我了解单行写作可能会令人愉悦,但它们可能会引起读者不必要的不​​适。

在我的编辑中:

  1. 我不再使用递归来标准化输入,而推荐使用第二种方法(在这种情况下为重载,如果您认为合理的话,可以随意重命名)。
  2. 我分析了将Instant转换为JString的逻辑,并调用了两次。
  3. 我将从LocalDateTimeLocalDateInstant的逻辑分解为几个重载方法,以使主逻辑在细节上更清晰
  4. >
  5. 我还使用了camelCase而不是snake_case,但这是个人喜好,如果您和您的团队喜好,请坚持使用snake_case

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

此外,这里的所有方法都是公共的,因为这是一个简单的纯脚本。我鼓励您限制可见性,以使只有想要公开的人可以看到(据我所知,我可能只将原始的timeToEpoch(params)保留为公开)。

您可以使用此代码here on 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")
}