Where should we use Template Method - pattern?
An application of the Template Method pattern has two main characteristics:
- There is a base class (in Java, one only with
protected
constructors and optionally declared asabstract
) which will be subclassed in client code. - There are two groups of methods defined in the base class: a) one or more template methods (typically only one) and one or more primitive operation methods (typically more than one). Each template method represents a high level operation, implemented in the base class itself in terms of the primitive operations, which are meant to be implemented/overriden in each specific subclass. Normally, the template method is public and non-overridable (
final
, in Java); its API documentation must specify precisely which primitive operation methods it calls, and when (that is, it must describe the "algorithm"). A primitive operation method, which represents a step in the algorithm, should be non-public but overridable (protected
, in Java), and can be of two types: a) an abstract method which must be implemented in the subclass; b) a method with a default/empty implementation which may be overriden in the subclass.
One good example in the Java 6 SDK is the execute()
method of the javax.swing.SwingWorker
class (it is a public final void
method). In this case, the primitive operation methods are doInBackground()
, process(List)
, and done()
. The first one is abstract and therefore requires an implementation in the subclass; it's called by the template method in a background thread. The other two have empty implementations and can optionally be overriden in the subclass; they are called during and at the end of processing, respectively, in the EDT (the Swing Event Dispatch Thread), to allow updates to the UI.
In my own experience, I have sometimes used this pattern.
One such case was a Java base class implementing the java.util.Iterator
interface, where next()
was the template method and there was only one primitive operation method responsible for instantiating a specific domain entity class (this was meant to be used when iterating over a list of persistent domain entity objects, using JDBC).
A better example in that same application was a base class where the template method implemented a multi-step algorithm intended to populate a "business entity maintenance screen" (using Swing) from a given list of persistent entities; primitive operations methods were called to 1) clear the current screen state, and 2) add an entity in a table view inside the screen; optionally, other primitive operations were called from the template method if the screen was editable.
In the end, I must say that although this certainly is a useful design pattern, not so often a situation comes up where it really is applicable. Simply having a base class with methods that get overriden in a subclass (a much more common situation, in my experience) is not enough, by itself, to qualify as an application of the pattern.
I tried to give you some real-world examples, and some common situations where Template Method pattern should be used.
When you want your program be "Open For Extension” and also “Closed for Modification”. This means that the behavior of the module can be extended, such that we can make the module behave in new and different ways as the requirements of the application change, or to meet the needs of new applications. However, The source code of such a module is inviolate. No one is allowed to make source code changes to it. In following example, you can add new manner of salary calculation (such as Remotely class) without changing the previous codes.
public abstract class Salary { public final void calculate() { System.out.println("First shared tasks is done."); getBaseSalary(); System.out.println("Second shared tasks is done."); } public abstract void getBaseSalary(); } public class Hourly extends Salary { @Override public void getBaseSalary() { System.out.println("Special Task is done."); } } public class Test { public static void main(String[] args) { Salary salary = .... salary.calculate(); } }
When you face many same line of codes that are duplicated through deferring just some steps of your algorithm. When you are implementing content of a method or function you can find some section of your code that vary from one type to another type. The feature of this sections are that one can redefine or modify these sections of an method or function without changing the algorithm's (method or function) main structure. For example if you want to solve this problem without this pattern you will face this sample:
function0: function1: ... functionN:
1 1 1
2 2 2
... ... ...
5 6 n
3 3 3
4 4 4
... ... ...
As you can see, section cods 5, 6, n are different vary from one function to another function, however you have shared sections such as 1,2,3,4 that are duplicated. Lets consider a solution with one of famous java libraries.
public abstract class InputStream implements Closeable {
public abstract int read() throws IOException;
public int read(byte b[], int off, int len) throws IOException {
....
int c = read();
....
}
....
}
public class ByteArrayInputStream extends InputStream {
...
public synchronized int read() {
return (pos < count) ? (buf[pos++] & 0xff) : -1;
}
...
}
When you as a designer of a framework, want that your clients just to use any executable code that is passed as an argument to your framework, which is expected to call back (execute) that argument at a given time. This execution may be immediate as in a synchronous callback, or it might happen at a later time as in an asynchronous callback. Lets consider one of famous ones.
public abstract class HttpServlet extends GenericServlet implements java.io.Serializable { protected void doGet(HttpServletRequest req, HttpServletResponse resp) { ... } protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { .... doGet(req, resp); ... } ... } } public class MyServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //do something ... } ... }
A Template method pattern provides a skeleton for performing any sort of algorithm or an operation, and it allows the sub-classes to re-define part of the logic.
Pros: Natural fit for building frameworks, so that parent framework classes can make callbacks into methods implemented in child.
Examples:
- java.util.AbstractList
- Servlet's doGet and doPost methods
- MDB's onMessage method
- Struts Action class
- Spring's data access classes
Cons: Restricts you to a single inheritance in Java.