'Loan' pattern

Ensures that a resource is deterministically disposed of once it goes out of scope.

The normal way to do this in Java is with a try ... finally block, which leads to ugly and fragile code, especially when there are multiple resources:

var r : Resource = null
try {
    r = getResource()
    useResource(r)
} finally {
    if(r != null) r.dispose()
}

This can be improved in Scala by encapsulating the disposal code in a function which takes a closure:

def using[A](r : Resource)(f : Resource => A) : A =
    try {
        f(r)
    } finally {
        r.dispose()
    }

The client code now looks like this:

using(getResource())(r =>
    useResource(r)
)

The using function above can be generalized to arbitrary resources by letting the resource type be a type parameter. Assuming that Resource is a mixin class requiring the definition of a dispose method, one can write:

def using[A, R <: Resource](r : R)(f : R => A) : A =
    try {
        f(r)
    } finally {
        r.dispose()
    }

Probably best of all, though, is to provide library functions that call getResource() internally. Then we would have, for each resource, a function that looks like this:

def withResource[A](f : Resource => A) : A = {
    val r = getResource()  // Replace with the code to acquire the resource
    try {
        f(r)
    } finally {
        r.dispose()
    }
}

Client code becomes very simple:

withResource{ r =>
    // do stuff with r....
}

Client code now obtains the resource ‘on loan’, and the compiler will guarantee that it is always returned. Care must still be taken to ensure that side-effects of f do not retain references to disposed resources.

 
patterns/loan.txt · Last modified: 2006/02/01 21:32 by 62.253.64.13
 
Recent changes RSS feed Valid XHTML 1.0 Driven by DokuWiki