scala akka 修炼之路6(scala函数式柯里化风格应用场景分析)

混江龙づ霸主 提交于 2020-01-19 19:54:45

胜败兵家事不期,包羞忍耻是男儿——斗牛士fighting,fighting,fighting...

    小象学习和使用scala也一段时间了,最初小象学习scala主要为了学习spark生态,可是深入学习scala的一些特性后。深深被scala函数式和面向对象的风格所折服,不得不赞美设计这门语言的设计者。小象大学阶段在使用MATLAB做数据分析和自己主动化设计时,就非常喜欢使用MATLAB的命令行和面向矩阵运算的风格编写分析代码。喜欢使用java编写层次化和清晰的模块接口,而这些Scala语言设计中都有非常好的设计。不得不说scala的函数式和面向对象风格。能够让想想随时发生。假设你是画家,使用scala写出来的代码更像一幅充满诗意的风景画。假设你是作家,写出的将是一个扣人心弦的跌宕起伏的大篇。

scala给不同类型的程序猿不同的体验和感受。而使用scala函数式柯里化风格。能够编写出更加抽象,功能化和高效的函数式代码。

    小象在定义主函数功能的时候经常出现这样的情况,函数体中的代码越写越长,本来能够拆分的功能,因为写代码的时候逻辑思绪根本停不下来,不愿意中途打断去定义那些繁琐的辅助函数,往往一个函数就一路走到头,最后使主函数代码段非常长。不便理解,功能复杂,须要后期慢慢拆分功能。小象在学习使用scala函数式柯里化风格后。在思绪停不下来又须要拆分功能的时候,就将定义好须要拆分的辅助功能函数的声明依照柯里化风格定义在函数声明中,继续完毕主函数功能,等主函数功能完毕后,在慢慢依照顺序去实现这些辅助功能。为了降低或隐藏辅助功能的传入简化接口中不必要的辅助方法參数传入,能够创建主函数的重载。使用scala柯里化风格能够简化主函数的复杂度,提高主函数的自闭性。提高功能上的可扩张性(事实证明:流水化生产式最高效和安全的,代码编写也一样。一个函数实现维护一个功能的完毕处理(逻辑处理。相关异常处理等)。也是极简设计。优秀代码体检的追求)。

    比如 设计一个获取本地文本文件的全部行数据的功能,主函数功能主要是创建文件流读取文件的全部行,在读取过程中,须要做非常多的辅助操作如推断本地文件是否存在和可读和关闭文件流。使用scala的函数式柯里化代码看上去将变得非常优雅

    
def getLines(filename:String):List[String]={
    getLines(filename)(isReadable)(closeStream)
}
def getLines(filename: String)(isFileReadable: (File) => Boolean)(closableStream: (Closeable) => Unit):List[String] = {
    val file = new File(filename)
    if (isFileReadable(file)) {
      val readerStream = new FileReader(file)
      val buffer = new BufferedReader(readerStream)
      try {
        var list: List[String] = List()
        var str = ""
        var isReadOver = false
        while (!isReadOver) {
          str = buffer.readLine()
          if (str == null) isReadOver = true
          else list = str :: list
        }
        list.reverse
      } finally {
        closableStream(buffer)
        closableStream(readerStream)
      }
    } else {
      List()
    }
  }

  def isReadable(file: File) = {
    if (null != file && file.exists() && file.canRead()) true
    else false
  }
  def closeStream(stream: Closeable) {
    if (null != stream) {
      try {
        stream.close
      } catch {
        case ex => Log.error(“[”+this.getClass.getName+”.closeStream]”,ex.getMessage)
      }
    }
  }

    小象觉得使用柯里化特性能够将复杂逻辑简单化。并能将非常多常漏掉的主函数业务逻辑之外的处理暴露在函数的定义阶段,提高代码的健壮性。使函数功能更加细腻化和流程化。

    比如 使用REST风格的HTTP资源请求的基于三层架构的MVC模式的WEB开发中前端的请求server段处理过程主要包括:第一步server端接受用户资源请求,第二步前端调度器代理接受用户资源请求,第三步检查当前请求的合法性,第四步创建对应的申请过滤处理链处理请求,第五步创建渲染视图,第六步响应用户请求。

    假设使用scala编写流程控制函数将非常easy和易于理解

/**
   * 用户资源请求=>调度器代理用户资源请求=>检查请求的合法性=>创建对应的资源申请责任链返回Model数据和视图URI=>创建视图=>响应用户请求
   */
  def serviceUserRequest[IN,M,V,OUT](requstInputData: IN)(dipatcherDelegeteOp: IN => M)(checkRequestValid: M => Boolean)(filterChains: M => M)(createResponseRestURLView: M => V)(createResponseStream:V=>OUT): OUT = {
    val request = dipatcherDelegeteOp(requstInputData)
    if (checkRequestValid(request)) {
      val model = filterChains(request)
      val view=createResponseRestURLView(model)
	 createResponseStream(view)
    } else {
      //error business handler
      “return error view URI Stream"
    }
  }


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!