как я могу рефакторинг это с помощью идей функционального программирования - PullRequest
0 голосов
/ 28 мая 2018

как я могу использовать функциональную парадигму программирования для удаления '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 голосов
/ 28 мая 2018

Разве что-то не так, как показано ниже:

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]())
}
0 голосов
/ 28 мая 2018

Вот более функциональная версия вашего кода.Он определяет объект с помощью метода 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 в parseAsLong.Последующие звонки на apply вызовут parseAsLong, который вместо этого вызовет parseByFastJsonLongKey.Единственный раз, когда обе JSON-функции вызываются, первый раз parseByFastJson завершается неудачно.После этого parseByFastJsonLongKey вызывается напрямую parseAsLong.

Использование объекта скрывает var, а сохранение функции в var является более чистым и эффективным, чем тестирование String каждый раз.

0 голосов
/ 28 мая 2018
  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]()
          }
        }
      }
    }
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...