Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 4.0

The Template Method Pattern abstracts away the details of several algorithms. The generic part of an algorithm is contained within a base class. Particular implementation details are captured within base classes. The generic pattern of classes involved looks like this:

Example

In this example, Accumulator captures the essence of the accumulation algorithm. The base classes Sum and Product provide particular customised ways to use the generic accumulation algorithm.

Code Block
abstract class Accumulator {
    protected initial
    abstract doAccumulate(total, v)
    def accumulate(values) {
        def total = initial
        values.each { v -> total = doAccumulate(total, v) }
        total
    }
}

class Sum extends Accumulator {
    def Sum() { initial = 0 }
    def doAccumulate(total, v) { total + v }
}

class Product extends Accumulator {
    def Product() { initial = 1 }
    def doAccumulate(total, v) { total * v }
}

println new Sum().accumulate([1,2,3,4])
println new Product().accumulate([1,2,3,4])

The resulting output is:

Code Block
10
24

In this particular case, you could use Groovy's inject method to achieve a similar result using Closures:

Code Block
Closure addAll = { total, item -> total += item }
def accumulated = [1, 2, 3, 4].inject(0, addAll)
println accumulated    // => 10

Thanks to duck-typing, this would also work with other objects which support an add (plus() in Groovy) method, e.g.:

Code Block
accumulated = [ "1", "2", "3", "4" ].inject("", addAll)
println accumulated    // => "1234"

We could also do the multiplication case as follows:

Code Block
Closure multAll = { total, item -> total *= item }
accumulated = [1, 2, 3, 4].inject(1, multAll)
println accumulated    // => 24

Using closures this way looks more like the Strategy Pattern but if we realise that the built-in inject method is the generic part of the algorithm for our template method, then the Closures become the customised parts of the template method pattern.