(Scala編程P.173)打開某個資源,對它進(jìn)行操作,然后關(guān)閉這個資源宫静。可以用類似如下的方法券时,將這個模式捕獲成一個控制抽象孤里,withPrintWriter打開某個資源并將這個資源“貸出”給函數(shù)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)
)
實踐:
讀取配置文件,都是打開文件橘洞,讀取配置文件內(nèi)容捌袜,可以考慮貸出模式
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]入?yún)⒂谜ㄔ妫琻ewInstance來構(gòu)造一個新的對象虏等,而且這個對象不能帶入?yún)ⅰ? else {
println(s"path = $fileName")
try {
val conf:Config = ConfigFactory.parseFile(file).withFallback(ConfigFactory.load())
fromConfig(conf)
} catch {
case ex: Exception => clz.newInstance()
}
}
}
}
這里用到了泛型類,可以傳入對于任何需要讀取配置參數(shù)類适肠,將讀取文件的方法通過fromConfig函數(shù)值傳進(jìn)來
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"))
}//傳入讀取文件的方法并生成相關(guān)的對象
}
def person: PersonConfig= personConfig
}
**Test.scala**
object Test {
def main(args: Array[String]): Unit = {
val itDepartmentConfig= new ITDepartmentConfig
println(itDepartmentConfig.person.toString)
}
}
上這里提到了不能直接new T()的問題霍衫,可以通過多加一個傳名參數(shù)來解決,就不需要使用ClassTag,使用ClassTag導(dǎo)致構(gòu)造函數(shù)中不可以帶入?yún)ⅰ7椒ㄈ缦拢?/p>
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
}
}
}
}
調(diào)用時
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
}