再一次讀到 Scala 中的“貸出模式(Loan Pattern)”這個術語,這才比上次稍了解一些。我的了解,此一模式大概是說,對于那些資源密集(resource-intensive)型對象的使用應該使用這一模式。
使用這一模式的原因是,既然資源集中在一個對象中,那麼使用者代碼就不能一直保持着獲得的所有資源,而應該在需要時就向資源供給方進行借貸,使用完畢之後立即歸還。
此外,Scala 中将函數也是對象,可以像參數那樣傳遞給另一個函數的特征使得貸出模式更加有意義。客戶代碼借貸了所需的資源,接下來如何使用這些資源以完成特定的任務則由客戶決定。就像我們向銀行貸款,這些錢的具體用途是客戶決定,也是客戶才明确的。
對于此類資源,有資料庫連接配接、IO操作等,這些是我們用完則務必立即釋放的資源。而且,資源使用完畢業意味着将被自動回收,我們不必操心資源回收的過程。
下面是一個 Scala 腳本代碼,客戶提供一個檔案名,利用writeFile 方法中能夠一個向該檔案寫入内容的 PrintWriter 對象。而具體如何使用這個 PrintWriter 對象則由使用者确定,使用完則由自動釋放。
def writeFile(fileName: File)(operation: PrintWriter => Unit) {
val writer = new PrintWriter(fileName) // 貸出資源writer
try{
operation(pw) // 客戶使用資源
}finally {
writer.close() // 用完則釋放被回收
}
}
上面 writeFile 方法的定義使用到了 Scala 中的curring技巧,是以才會看到 writeFile 定義之後有兩個參數清單(即兩個小括号對),後面的參數 operation 用于傳入客戶具體想要的操作(即怎麼使用資源)。
客戶代碼如下:
val file = new File("test.txt")
writeFile(file) {
// 使用資源的具體操作
writer => writer.println("haolloyin ...\r\n" +
new java.util.Date())
執行該腳本,會發現在目前目錄下生成一個 test.txt 檔案,裡面的内容如下:
haolloyin...
Fri Sep 03 22:44:18 CST 2010
在這個例子中,客戶對資源的使用完全是自定義的,如上面的writer => writer.println(…) 所示。但是有時候我們會遇到一些本身已經預定義好所具備操作的資源,那麼此時可以結合 Singleton Object 單例對象的使用特點對其伴生類所代表的資源進行建立和使用。
同時使用資源類與其單例對象的用意在于,確定該資源隻能通過伴生對象進行合法通路,控制好資源的客戶源的合法性。這在《Scala 鉛筆書》中有下面這個例子,我把代碼拷貝并注釋如下:
// 主構造器私有,限制其對象(資源)的建立範圍
class Resource private() {
println("Starting transaction...") // 被作為主構造器的語句而執行
// 資源的收回也是内部處理
private def cleanUp() { println("Ending transaction...") }
// 資源類本身預定義的具體操作
def op1 = println("Operation 1")
def op2 = println("Operation 2")
def op3 = println("Operation 3")
// 單例對象,客戶使用資源的入口
object Resource {
def use(codeBlock: Resource => Unit) {
val resource = new Resource // 貸出資源
try {
codeBlock(resource) // 使用資源
finally {
resource.cleanUp() // 資源被回收
}
客戶代碼如此使用資源:
Resource.use { resource =>
resource.op1
resource.op2
resource.op3
resource.op1 // 任意的操作調用序列
程式輸出:
Starting transaction...
Operation 1
Operation 2
Operation 3
Ending transaction...
本文轉自 xxxx66yyyy 51CTO部落格,原文連結:http://blog.51cto.com/haolloyin/387138,如需轉載請自行聯系原作者