(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
}
网友评论