Template Method


Definition

Provide an abstract definition for a method or a class and redefine its behavior later or on the fly without changing its structure.

Where to use & benefits

Examples

For example, a loan application process may take several steps to finish. Let's assume the steps are as follows:

You may use a template method to hold the process steps together without considering the real implementation in the subclass.

abstract class CheckBackground {
  
    public abstract void checkBank();
    public abstract void checkCredit();
    public abstract void checkLoan();
    public abstract void checkStock();
    public abstract void checkIncome();

  //work as template method
    public void check() {
        checkBank();
        checkCredit();
        checkLoan();
        checkStock();
        checkIncome(); 
    }
}

class LoanApp extends CheckBackground {
    private String name;
   
    public LoanApp(String name) {
        this.name = name;
    }
    
    public String getName() {
        return name;
    }

    public void checkBank() {
        //ck acct, balance
        System.out.println("check bank...");
    }

    public void checkCredit() {
        //ck score from 3 companies
        System.out.println("check credit...");
    }

    public void checkLoan() {
        //ck other loan info
        System.out.println("check other loan...");
    }

    public void checkStock() {
        //ck how many stock values
        System.out.println("check stock values...");
    }

    public void checkIncome() {
        //ck how much a family make
        System.out.println("check family income...");
    }
   
    //other methods
}

class TestTemplate {
    public static void main(String[] args) {
        
        LoanApp mortgageClient = new LoanApp("Judy");
        System.out.println("\nCheck client " + mortgageClient.getName()+ " Mortgage loan application. ");
        mortgageClient.check();
        
        LoanApp equityloanClient = new LoanApp("Mark");
        System.out.println("\nCheck client " + equityloanClient.getName()+ " equity loan application. ");
        equityloanClient.check();
    }
}

 C:\ Command Prompt
 
C:\> javac TestTemplate.java
C:\> java TestTemplate

Check client Judy Mortgage loan application.
check bank...
check credit...
check other loan...
check stock values...
check family income...

Check client Mark equity loan application.
check bank...
check credit...
check other loan...
check stock values...
check family income...

C:\>


Method overloading and method overriding are good examples of template method pattern. For example,

The add() in the following code example is a template method. It can take any numerical primitive types and the result can be casted to the type you want.

//coercion polymorphism
abstract class Add {
   public abstract double add(double d1, double d2);//template
}
class AddAnyTypeNumber extends Add{
    public double add(double d1, double d2) {
        return d1 + d2;
    }
}
class Test {
   public static void main(String[] args) {
       double d1 = 10.5, d2 = 9.5;
       float f1 = 11.5f, f2 = 12.5f;
       long l1 = 1, l2 = 2;
       int i1 = 3, i2 = 4;
       short s1 = 7, s2 = 8;
       byte b1 = 5, b2 = 6;
       
       AddAnyTypeNumber addNumber = new AddAnyTypeNumber();
       
       System.out.println(addNumber.add(d1,d2));
       System.out.println((float)addNumber.add(f1,f2));
       System.out.println((long)addNumber.add(l1,l2));
       System.out.println((int)addNumber.add(i1,i2));
       System.out.println((short)addNumber.add(s1,s2));
       System.out.println((byte)addNumber.add(b1,b2));
   }
}

 C:\ Command Prompt
 
C:\> java Test
20.0
24.0
3
7
15
11

Note that the side effect of using coercion polymorphism is casting in and casting out if you need specific type to do the work. If you forget to do so, you may have unexpected result and it is hard to debug.

If you don't have template method pattern concept or don't know Java type promotion technique, you may write code in the following way:

abstract class Add {
   public abstract double add(double d1, double d2);
   public abstract float add(float d1, float d2);
   public abstract long add(long d1, long d2);
   public abstract int add(int d1, int d2);
   public abstract short add(short d1, short d2);
   public abstract byte add(byte d1, byte d2);
}
class AddNumber extends Add{
    public double add(double d1, double d2) {
        return d1 + d2;
    }
    public float add(float f1, float f2) {
        return f1 + f2;
    }
    public long add(long l1, long l2) {
        return l1 + l2;
    }
    public int add(int i1, int i2) {
        return i1 + i2;
    }
    public short add(short s1, short s2) {
        return (short)(s1 + s2);
    }
    public byte add(byte b1, byte b2) {
        return (byte)(b1 + b2);
    }
}
class Test {
   public static void main(String[] args) {
       double d1 = 10.5, d2 = 9.5;
       float f1 = 11.5f, f2 = 12.5f;
       long l1 = 1, l2 = 2;
       int i1 = 3, i2 = 4;
       short s1 = 7, s2 = 8;
       byte b1 = 5, b2 = 6;
       
       AddNumber addNumber = new AddNumber();
       
       System.out.println(addNumber.add(d1,d2));
       System.out.println(addNumber.add(f1,f2));
       System.out.println(addNumber.add(l1,l2));
       System.out.println(addNumber.add(i1,i2));
       System.out.println(addNumber.add(s1,s2));
       System.out.println(addNumber.add(b1,b2));
   }
}

 C:\ Command Prompt
 
C:\> java Test
20.0
24.0
3
7
15
11

Without using template method pattern, you may write more lines of code. The good thing is that you don't have any side effect by using specific designed method and you don't need to cast in or out.

Return to top