プログラミングでは、「リソースを取得したら解放する」パターンが頻出します。例えば、
などがあります。コード中でこの「借りたら返す」を確実に行うのがLoan Patternです。
def query(sql:String) = {
val connection = db.getConnection
val result = connection.query(sql) // もしクエリの実行中に例外が発生したら?
connection.close // このコードが確実に呼ばれる保障がない
result
}
try … finallyで囲むと例外(exception)に強いコードが書ける。
def query(sql:String) = {
val connection = db.getConnection
try
connection.query(sql) // クエリの実行中に例外が発生しても。。。
finally
connection.close // このコードは確実に呼ばれる
}
しかし、実際にはqueryだけでなくupdateなどもしたいはず。
def update(sql:String) = {
val connection = db.getConnection
try
connection.update(sql)
finally
connection.close
}
同じようなコードなのに、繰り返して書かなくてはいけない。
Scalaではコードブロック(つまり関数)を引数として渡せるので、パターンの再利用が可能
// loan pattern
def open[A](body:Connection => A) : A = {
val connection = db.getConnection
try
body(connection)
finally
connection.close
}
// loan patternの利用
def query(sql:String) = open(_.query(sql))
def update(sql:String) = open(_.update(sql))
C++で似たようなパターンを実現するには以下の手法がある