ICE09 . playing with java, scala, groovy and spring .

Playing with Spring

Scala Mashup Series: The Template Method in Java, Spring and Scala

Posted by ice09 on November 9, 2009

Continuing the Scala Mashup Series, this post is about a quite important, often used, but also controversial pattern: The Template Method.

In general, there are great explanations of the pattern in Wikipedia and of course in Head First Design Patterns.

Criticism

A very good summary of the Template Method pattern especially in comparison to the Strategy pattern is on stackoverflow.com:

The Template pattern does compile-time algorithm selection by subclassing.
The Strategy pattern does run-time algorithm selection by containment.

Example

Imagine you want to arrange a dinner. The entire algorithm for arranging a dinner is predefined:

  1. Invite your guests
  2. Go shopping
  3. Clean your fridge to provide enough space
  4. Prepare the meal
  5. Server the meal
  6. Wash the dishes

Now, some parts of this algorithm (which in its entirety is called arrange) are fixed (invariant parts). Other parts are highly dependant on the meal you want to prepare (variant parts).
In Template Method, the algorithm itself is described in a public accessible method, eg. arrange(), which combines and calls the variant and invariant methods. The invariant methods are implemented in the abstract super class. The variant parts are implemented in the concrete classes, eg. BratwurstDinner, which implements the concrete way to do shopping for the BratwurstDinner, as well as the preparation of the Bratwurst itself.
The important part is the compile-time binding – the implementing, concrete classes cannot change their implementation during runtime.
This makes the Template Method almost ideal for framework creation, when you want to provide abstract algorithms with certain concrete implementations (think of abstract database layers, with an algorithm which cares for opening & establishing connections, handles exceptions and cleans up nicely after doing … the variant part, which is implemented in the concrete classes).

Here is the dinner example using the Template Method pattern

Here is the dinner example using the Strategy pattern

There are two clever blog posts, one about disadvantages of the Template Method pattern, and one mentioning a possible alternative in languages with first class functions like Scala.

Language comparison: Java, Scala, Spring

We will happily leave out the Java example, since it is just too obvious. In the Wikipedia article a sample is given, together with the class diagram it should be pretty obvious how Template Method is implemented in Java. The only thing to keep in mind is to set the super class abstract, as well as the variant methods – which are then implemented (using @Override) in the concrete classes.

Scala

In Scala there are is the intuitive way of implemeting the Template Method, analogous to Java:

abstract class DinnerEvent {

  def arrange(): Unit = {
    makeGuestList
    doShopping
    cleanFridge
    prepareMeal
    serveMeal
    washDishes
  }

  def prepareMeal(): Unit
  def doShopping(): Unit

  def makeGuestList(): Unit = {
    println("making guest list...")
  }

  def cleanFridge(): Unit = {
    println("cleaning fridge...")
  }

  def serveMeal(): Unit = {
    println("serving meal...")
  }

  def washDishes(): Unit = {
    println("washing dishes...")
  }

}

trait TurkeyDinner {

  def doShopping(): Unit =  {
    println("...buying turkey")
  }

  def prepareMeal(): Unit =  {
    println("...preparing turkey")
  }

}

object TemplateMethod {

  def main(args:Array[String]) = {
    val dinner = new DinnerEvent with TurkeyDinner
    dinner.arrange()
  }

}

However, in languages with first class functions, it is too tempting to use the Strategy pattern:

class DinnerEventWithStrategy(shoppingStrategy: () => Unit, preparingStrategy: () => Unit) {

  def arrange(): Unit = {
    makeGuestList()
    shoppingStrategy()
    cleanFridge()
    preparingStrategy()
    serveMeal()
    washDishes()
  }

  def makeGuestList(): Unit = {
    println("making guest list...")
  }

  def cleanFridge(): Unit = {
    println("cleaning fridge...")
  }

  def serveMeal(): Unit = {
    println("serving meal...")
  }

  def washDishes(): Unit = {
    println("washing dishes...")
  }

}

object Closure {

  def turkeyShoppingStrategy(): Unit = {
    println ("...shopping turkey strategy")
  }

  def turkeyPreparationStrategy(): Unit = {
    println ("...preparing turkey strategy")
  }

  def main(args:Array[String]) = {
    val dinner = new DinnerEventWithStrategy(turkeyShoppingStrategy, turkeyPreparationStrategy)
    dinner.arrange()
  }

}

So, you should choose wisely, both patterns definitely have their scope of application – just keep in mind that Strategy also uses composition over inheritance, which is always a good advise.

…and what about Spring?

This is interesting, Spring uses the Template Method a lot – and many think it is one of their greatest strengths.
But wait … the Template Method pattern? Not really. The Spring Framework templates in fact are not implementing the Template Method pattern, even if it feels this way.
Let’s examine a small usage example of Spring’s JdbcTemplate:

package com.commons.sample.dao;

import java.util.List;

import org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;

public class JdbcSimpleDao extends SimpleJdbcDaoSupport implements SimpleDao {

	final static String single	= "select id, name from test where id = ?"; 
	final static String list 	= "select id, name from test"; 

	public Simple getSimpleById(int id) {
		return getSimpleJdbcTemplate().queryForObject(single, 
				ParameterizedBeanPropertyRowMapper.newInstance(Simple.class), id);
	}

	public List<Simple> getSimples() {
		return getSimpleJdbcTemplate().query(list, 
				ParameterizedBeanPropertyRowMapper.newInstance(Simple.class));
	}

}

What is happening here? Even though the class extends SimpleJdbcDaoSupport, it would not have to.
The Method query(…) takes the SQL and a ParameterizedBeanPropertyRowMapper.newInstance(Simple.class), which defines a row mapper that creates an object of class Simple – this certainly describes a strategy. So, even the so-called Spring Templates actually uses the Strategy pattern.

Summary

The Template Method is a powerful pattern. Use it if you create a framework, since you can inject certain functionality in the implementing classes at compile time, which let the user of your framework extend it easily, but in a controlled and “traceable” way. For Java, it is a natural way to enable users of your classes to extends the functionality at certain points.
In languages with first-order functions (or closures), like Scala, it might feel more natural to use the Strategy pattern instead. However, keep in mind that the patterns are not completely identical.

About these ads

2 Responses to “Scala Mashup Series: The Template Method in Java, Spring and Scala”

  1. Your scala example isn’t actually using first-class functions, but a feature called “by-name” parameters. Function arguments are denoted by declaring the type of the argument as one of the FuncitonN traits, or by using the shorthand () => (in your case, () => Unit). Notice the subtle difference:

    by-name parameter: f: => Unit
    function argument: f: () => Unit

    Function instances are objects of one of the FunctionN types, and so have an apply method (among others). By-name parameters are typed by the name to the right of the =>; they are specifically not Function instances. Instead, the computation of the value is deferred until it is actually referenced. What that means for your example is that the DinnerEventWithStrategy constructor isn’t taking function arguments, but instead by-name arguments of type Unit (in scala, the literal “()” is essentially a constant of type Unit). As such, you could pass unit values to it:

    new DinnerEventWithStrategy((), ())

    In your example, the execution of the methods turkeyShoppingStrategy and turkeyPreparationStrategy is simply being deferred until they are referenced in the arrange method (because those methods are no-arg methods that return a Unit (callback-style), it’s hard to see the difference).

    Further indication would be to try and call the apply method on shoppingStrategy in your arrange method (shoppingStrategy.apply()). You’ll be greeted with:

    error: value apply is not a member of Unit

    Because it’s a (deferred) Unit instance, not a function. That is, this won’t compile:

    class Foo(f: => Unit) { def doIt = f.apply() }

    But this will:

    class Foo(f: () => Unit) { def doIt = f.apply() }

    • ice09 said

      You are absolutely right, I tried to correct it and hope it’s ok now. However, for a beginner, this is difficult to grasp, since it looks quite similar.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
Follow

Get every new post delivered to your Inbox.

%d bloggers like this: