我怎样才能使用函数式编程思想来重构它

时间:2018-05-28 06:07:28

标签: scala functional-programming

我如何使用功能编程范例来删除' var'在下面的代码片段中,我试图将json字符串解析为map [String,Object],如果失败,我将其解析为map [Long,Object],所以' KEY_TYPE'只是一个开关,我如何在函数式编程中实现开关逻辑?

   var KEY_TYPE = "String"

  /**
    * 解析json格式 先尝试一次解析成Map[String,Object] 失败则解析成Map[Long,Object]
    *
    * @param runSnap
    * @return
    */
  def parseJson(runSnap: String): Map[Long, Object] = {
    Try {
      if (KEY_TYPE == "String") {
        JSONUtils.parseByFastJson(runSnap).asScala
          .toMap.map(entry => entry._1.toLong -> entry._2)
      } else {
        JSONUtils.parseByFastJsonLongKey(runSnap).asScala
          .toMap.map(entry => Long2long(entry._1.toLong) -> entry._2)
      }
    } match {
      case Success(result) => result
      case Failure(exception) => {
        println("json parse excepiton " + exception)
        if (KEY_TYPE == "String") {
          KEY_TYPE = "Long"
          parseJson(runSnap)
        } else {
          Map[Long, Object]()
        }
      }
    }
  }

3 个答案:

答案 0 :(得分:0)

  1. 不要使用魔法字符串,这容易出错。定义一个小枚举,或者至少使用Boolean。我将Boolean用于KEY_TYPE
  2. 只需将KEY_TYPE作为(默认)参数传递:

    def parseJson(runSnap: String, keyTypeIsString: Boolean = true): 
    Map[Long, Object] = {
      Try {
        if (keyTypeIsString) {
          JSONUtils.parseByFastJson(runSnap).asScala
            .toMap.map(entry => entry._1.toLong -> entry._2)
        } else {
          JSONUtils.parseByFastJsonLongKey(runSnap).asScala
            .toMap.map(entry => Long2long(entry._1.toLong) -> entry._2)
        }
      } match {
        case Success(result) => result
        case Failure(exception) => {
          println("json parse excepiton " + exception)
          if (keyTypeIsString) {
            parseJson(runSnap, false)
          } else {
            Map[Long, Object]()
          }
        }
      }
    }
    

答案 1 :(得分:0)

不是下面的内容:

def parseJson(runSnap: String): Map[Long, Object] = {
   Try(JSONUtils.parseByFastJson(runSnap).asScala .toMap.map(entry => entry._1.toLong -> entry._2))
   .toOption
   .orElse(Try(JSONUtils.parseByFastJsonLongKey(runSnap).asScala).toOption)
   .getOrElse( Map[Long, Object]())
}

答案 2 :(得分:0)

这是您的代码的更多功能版本。它定义了一个带有classpath 'com.google.gms:google-services:4.0.1'方法的对象,它可以像原始函数一样使用。

apply

最初object parseJson { private def parseAsString(runSnap: String): Map[Long, Object] = Try { JSONUtils.parseByFastJson(runSnap).asScala .toMap.map(entry => entry._1.toLong -> entry._2) } match { case Success(result) => result case _ => parser = parseAsLong _ parser(runSnap) } private def parseAsLong(runSnap: String): Map[Long, Object] = Try { JSONUtils. parseByFastJsonLongKey(runSnap).asScala .toMap.map(entry => Long2long(entry._1.toLong) -> entry._2) }.getOrElse(Map[Long, Object]()) private val parser = parseAsString _ def apply(runSnap: String) = parser(runSnap) } 设置为parser,因此parseAsString调用apply来调用parseAsString。但是当parseByFastJson中的解析失败时,它会将parseAsString设置为parser。对[{1}}的后续调用将调用调用parseAsLong的{​​{1}}。调用两个JSON函数的唯一时间是发生时间apply失败。之后,parseAsLong直接调用parseByFastJsonLongKey

使用对象可以隐藏parseByFastJson,并且在parseByFastJsonLongKey中存储函数比每次测试parseAsLong更清晰,更有效。