美文网首页
使用控制抽象函数(贷出模式loan pattern)

使用控制抽象函数(贷出模式loan pattern)

作者: no0one | 来源:发表于2019-08-28 09:59 被阅读0次

    (Scala编程P.173)打开某个资源,对它进行操作,然后关闭这个资源。可以用类似如下的方法,将这个模式捕获成一个控制抽象,withPrintWriter打开某个资源并将这个资源“贷出”给函数op

    def withPrintWriter(file: File, op: PrintWriter => Unit): Unit = {
      val writer = new PrintWriter(file)
      try {
        op(writer)
      } finally {
        writer.close()
      }
    }
    
    withPrintWriter(
      new File("date.txt"),
      writer => writer.println(new java.util.Date)
    )
    

    实践:

    读取配置文件,都是打开文件,读取配置文件内容,可以考虑贷出模式

    ReadConfigFile.scala

    import com.typesafe.config.{Config, ConfigFactory}
    
    import scala.reflect.ClassTag
    
    class ReadConfigFile[T:ClassTag](clz: Class[T]){
      def read(fileName: String)(fromConfig: Config => T): T = {  //柯里化
        val file = new File(fileName)
        if (!file.exists())  clz.newInstance()//不能直接new T(),scala不能识别,需要通过ClassTag,增加Class[T]入参用,newInstance来构造一个新的对象,而且这个对象不能带入参。
        else {
          println(s"path = $fileName")
          try {
            val conf:Config = ConfigFactory.parseFile(file).withFallback(ConfigFactory.load())
            fromConfig(conf)
          } catch {
            case ex: Exception => clz.newInstance()
          }
        }
      }
    }
    

    这里用到了泛型类,可以传入对于任何需要读取配置参数类,将读取文件的方法通过fromConfig函数值传进来

    PersonConfig.scala

    class PersonConfig{
      var name: String = ""
      var age: Int = 0
    
      override def toString: String = {
        "name=" + name + " age=" + age
      }
    }
    
    object PersonConfig{
      def createPersonConfig(config: Config): PersonConfig= {
        val PersonConfig= new PersonConfig
        PersonConfig.name = config.getString("name ")
        PersonConfig.age= config.getInt("age")
        PersonConfig
      }
    }
    

    ITDepartmentConfig.scala

    class ITDepartmentConfigextends ReadConfigFile(classOf[PersonConfig]){
      private val personConfig: PersonConfig= {
        read("person.conf") { config =>
          PersonConfig.createServerConfig(config.getConfig("person_config"))
        }//传入读取文件的方法并生成相关的对象
      }
    
      def person: PersonConfig= personConfig
    }
    
    **Test.scala**
    object Test {
      def main(args: Array[String]): Unit = {
        val itDepartmentConfig= new ITDepartmentConfig
        println(itDepartmentConfig.person.toString)
      }
    }
    

    上这里提到了不能直接new T()的问题,可以通过多加一个传名参数来解决,就不需要使用ClassTag,使用ClassTag导致构造函数中不可以带入参。方法如下:

    class ReadConfigFile[T]{
      def read(fileName: String)(fromConfig: Config => T)(emptyObject: => T): T = {
        val file = new File(fileName)
        if (!file.exists())  emptyObject
        else {
          println(s" path = $fileName ")
          try {
            val conf:Config = ConfigFactory.parseFile(file).withFallback(ConfigFactory.load())
            fromConfig(conf)
          } catch {
            case ex: Exception => emptyObject
          }
        }
      }
    }
    

    调用时

    class RESTServerConfig extends ReadConfigFile[ServerConfig] with Subject {
      private val serverConfig: ServerConfig = {
        read(FileUtil.getConfigPath + "rest-server.conf") { config =>
          ServerConfig.createServerConfig(config.getConfig("rest_server_config"))
        }(new ServerConfig())
      }
    
      def server: ServerConfig = serverConfig
    }
    

    相关文章

      网友评论

          本文标题:使用控制抽象函数(贷出模式loan pattern)

          本文链接:https://www.haomeiwen.com/subject/atxpectx.html