CSC/ECE 517 Fall 2012/ch2a 2w19 is: Difference between revisions
Line 149: | Line 149: | ||
The benefits of using this design pattern are<ref>http://snehaprashant.blogspot.com/2008/09/template-method-pattern.html</ref>: | The benefits of using this design pattern are<ref>http://snehaprashant.blogspot.com/2008/09/template-method-pattern.html</ref>: | ||
* There is no code duplication between classes, which is a good coding practice as well as [http://en.wikipedia.org/wiki/Don't_repeat_yourself DRY]. | * There is no code duplication between classes, which is a good coding practice as well as [http://en.wikipedia.org/wiki/Don't_repeat_yourself DRY]. This is also a good form of code refactoring which is a good practice to follow. | ||
* Polymorphism is exploited to a great extent. The Abstract class calls the correct Concrete classes' methods automatically. | * Polymorphism is exploited to a great extent. The Abstract class calls the correct Concrete classes' methods automatically. | ||
* This pattern favors [http://en.wikipedia.org/wiki/Inheritance inheritance] over [http://www.cs.sjsu.edu/~pearce/cs251b/principles/crp.htm composition]<ref>http://en.wikipedia.org/wiki/Composition_over_inheritance</ref>. The advantage of composition is that [http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming) encapsulation] is not destroyed and the advantage of inheritance (according to [http://c2.com/cgi/wiki?GangOfFour GoF]) is that if the subclasses modify only certain aspects of the behavior of the super class then it is easier to modify the reused code, making the implementation(s) more flexible and efficient. | * This pattern favors [http://en.wikipedia.org/wiki/Inheritance inheritance] over [http://www.cs.sjsu.edu/~pearce/cs251b/principles/crp.htm composition]<ref>http://en.wikipedia.org/wiki/Composition_over_inheritance</ref>. The advantage of composition is that [http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming) encapsulation] is not destroyed and the advantage of inheritance (according to [http://c2.com/cgi/wiki?GangOfFour GoF]) is that if the subclasses modify only certain aspects of the behavior of the super class then it is easier to modify the reused code, making the implementation(s) more flexible and efficient. | ||
* As the templateMethod() takes care of the overall semantics and the derived classes implement the details and so on, it is easy for others to understand the code for future purposes. | |||
===Liabilities=== | ===Liabilities=== |
Revision as of 19:39, 27 October 2012
Template Method Pattern
Note that this is one of many behavioral design pattern and is not to be confused with C++ Templates.
Introduction
A template is a previously set format that other applications use as a starting point, instead of redefining the format each time<ref>http://www.oodesign.com/template-method-pattern.html</ref>. As you can imagine, Software Engineering contains many such patterns in order to develop software and applications. One such pattern is the Template Method Pattern<ref>http://en.wikipedia.org/wiki/Template_method_pattern</ref>. The Template Method Pattern is a behavioral design pattern that defines an algorithm skeleton in a base class, with abstract definitions that derived classes can override to provide concrete behavior. The skeleton is called the template method and the subclasses or derived classes implement the algorithm, sometimes with minor modifications.
In object-oriented design, the base class defines the template by stating the steps of the algorithm using abstract methods that its derived classes implement in a more concrete manner. In this manner, the template method pattern stores the algorithm in one place while other classes implement it, which is good object-oriented(OO) design. Also, the designer can decide which of the algorithm steps are to be standard and which of these are to be customizable<ref>http://sourcemaking.com/design_patterns/template_method</ref>. These standard steps are implemented concretely in the derived classes using the abstract base class's definitions and the customizable steps are either implemented in the derived classes, or not at all. These customizable steps serve as placeholders, or hooks<ref>http://en.wikipedia.org/wiki/Hook_method#Hook_methods</ref>, that the derived classes can supply or not, as they choose. So basically it is used when programmers want to fix the order of operations used in a method, but allow some amount of flexibility such that the subclasses can implement some of these operations in their own manner<ref>http://userpages.umbc.edu/~tarr/dp/lectures/Template.pdf</ref>.
The template method pattern thus, is fundamentally a code reuse technique. It is used whenever programmers want to localize common behavior in subclasses and place it in a super class to avoid code duplication. Hence it is an example of code refactoring.
Problems Solved by this pattern
Template Method pattern is a type of a behavioral design pattern which defines a skeleton for an algorithm which cannot be implemented in that class due to calls to methods that are abstract but can be implemented in the child classes. The template method cannot be overridden in the child classes as it is defined as a final method in the parent class.
Suppose we have a portal where we allow users to book tickets to travel from source to destination. The problem we face here is that, we want all users to use a standard way of booking tickets and travelling. They could travel by bus, train or flight but we want them to follow a certain number of steps in the same order before they can see the confirmation page. We do not want one user to pay first and then select a date and time and a flight and the other user to do this the other way round. However, the mode of transport for the travel may be different for every user and the source and destination may also be different for each of them.
This is the ideal situation in which we would use the Template Method pattern. The parent class will have a template method defined with an algorithm skeleton that says that the steps to be followed will be select the mode of transport, then select the source, then destination and then the date of travel and finally mode of payment.
However, the methods defining the selection of these functionalities can be implemented in different ways depending on what the subclass is. These methods in the parent class are kept abstract but the template method in the parent is made final. The template method calls the functions in a certain order.
Let us show this with a concrete code.
public class Portal { public final void TicketBooking() { TransportMode(); if(int i < 4) SourceAndDate(); else DestinationAndDate(); Payment(); } abstract public MethodA(); abstract public MethodB(); abstract public MethodC(); }
public class Feedback_response extends Response { TransportMode() { //some definition } SourceAndDate() { //some definition } DestinationAndDate() { //some definition } Payment() { //some definition } }
Each of the sub classes inheriting from this class can then provide a concrete definition to these abstract methods in a way they but the method template is final and must be used in the same way.
Structure and Protocol
The figure below depicts the structure of the Template Method Pattern:
As seen above, there are two main types of classes in this pattern: the Abstract (or super) class and the Concrete (or derived) class<ref>http://java.dzone.com/articles/design-patterns-template-method</ref>. The Abstract class is made final so that it cannot be overriden and it is the class that contains the templateMethod(). All its methods that are to be deferred to the sub classes are made abstract. The Concrete class on the other hand implements all the abstract methods of the Abstract class. Different Concrete classes can implement the templateMethod() in different ways as long as they stick to the skeleton specified in the Abstract class.
This pattern utilizes the Hollywood Principle: Don't call us, we'll call you. The templateMethod() in the Abstract class has control over the overall process and calls the Concrete class method as and when required. The use of the Hollywood principle enables derived classes to hook onto super classes, instead of the usual dependency of derived classes on super classes.
A quick look at the Abstract class shows that there are four main types of methods involved:
- Abstract Methods: These methods have no implementation in the Abstract class and are to implemented by the Derived classes.
- Concrete Methods: These are complete methods that the Derived classes may find useful. In most cases, they are standard utility/housekeeping functions.
- Hook Methods: These methods can be overridden by the Derived classes (as mentioned above).
- Template Methods: These methods call the above three methods without implementing them and provide a skeleton for the algorithm in question.
Roles and Responsibilities
A role is a abstraction mechanism, based upon general concepts; i.e., it is a natural element in our concept formulation<ref>http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=6&cad=rja&ved=0CEIQFjAF&url=http%3A%2F%2Fciteseerx.ist.psu.edu%2Fviewdoc%2Fdownload%3Fdoi%3D10.1.1.51.6558%26rep%3Drep1%26type%3Dpdf&ei=9liLUKenDYSi8gS7toCgBg&usg=AFQjCNGxhD-P6SxAYmMRh1fs5KiPN2IKTg&sig2=3gkiXtaPnHoyT3gYw-QVeg</ref>. Each Concrete class assumes a new role based upon the concept formulation involved in the Template Method Pattern in question. Each Concrete class (or role) implements the templateMethod() with few or no modifications to the original algorithm and with each role, comes a separate set of responsibilities. These responsibilities will be the same with respect to the algorithm skeleton, but will differ where the roles add their own implementations to it.
Consider the following Abstract Class:
public class Employee{ public final void EmployeeOperations(){ CheckIN(); DoWork(); CheckOut(); } abstract public ExtraResponsibility1(); abstract public ExtraResponsibility2(); }
Now consider the following two Concrete Classes:
public class Clerk extends Employee{ CheckIN(){ //check in at work every day on time. } DoWork(){ //arrange items in store. } CheckOut(){ //check out at work every day when leaving. } ExtraResponsibility1(){ //interact with customers. } }
public class Manager extends Employee{ CheckIN(){ //check in at work every day on time. } DoWork(){ //manage clerk's duties. } CheckOut(){ //check out at work every day when leaving. } ExtraResponsibility1(){ //decide on Employee of the Month awardee. } ExtraResponsibility2(){ //interact with suppliers. } }
As you can see above, the Concrete classes assume a different role (clerk and manager) and both of them have different responsibilities (as specified in the comments under each method). Also note that the hook methods ExtraResponsibility1() and ExtraResponsibility2() are defined only as required in the derived classes. These hook methods may also be used inside the templateMethod() if a one or more derived classes need to perform certain other steps in order to proceed to the next one, thus making it even more flexible and efficient.
Benefits and Liabilities
Benefits
The benefits of using this design pattern are<ref>http://snehaprashant.blogspot.com/2008/09/template-method-pattern.html</ref>:
- There is no code duplication between classes, which is a good coding practice as well as DRY. This is also a good form of code refactoring which is a good practice to follow.
- Polymorphism is exploited to a great extent. The Abstract class calls the correct Concrete classes' methods automatically.
- This pattern favors inheritance over composition<ref>http://en.wikipedia.org/wiki/Composition_over_inheritance</ref>. The advantage of composition is that encapsulation is not destroyed and the advantage of inheritance (according to GoF) is that if the subclasses modify only certain aspects of the behavior of the super class then it is easier to modify the reused code, making the implementation(s) more flexible and efficient.
- As the templateMethod() takes care of the overall semantics and the derived classes implement the details and so on, it is easy for others to understand the code for future purposes.
Liabilities
The Template Method Pattern suffers from the following problems<ref>http://www.oodesign.com/template-method-pattern.html</ref>:
- The templateMethod() cannot be overridden. If the program skeleton needs to be changed then the entire structure and all the classes must be modified accordingly.
- The base class is normally Abstract. If it were to be made Concrete, then the primitive methods would not be abstract and ambiguity would arise due to the fact that new programmers to the code would be unsure as to which methods could be overridden and which could not.
- The amount of private methods should be as few as possible in order to make the implementation of the templateMethod() as easy as possible.
- Customizing hooks proves to be problematic. Hooks are basically empty functions in the Abstract class that Concrete classes implement if they wish to modify the algorithm or add to its functionality. As the skeleton is defined once for use it is hard to predict the locations for adding hooks to the skeleton, as the programmer may not know all the possible ways of customizing the templateMethod() to suit each individual Concrete class. Also, defining a hook before every method and after is inefficient and impractical in large scenarios.
Comparison with other design patterns
Comparison with Adapter Design Pattern
Characteristics | Adapter Design Pattern | Template Method Design Pattern | Explanation |
---|---|---|---|
Design Pattern Category | Structural Pattern | Behavioral Pattern | In Structural patterns, the focus is on relationships between objects and how they together form larger components whereas in Behavioral patterns, the focus is on communication between objects and what each object does <ref name='StructuralBehavioral'>Design Patterns: Structural and Behavioral http://twu.seanho.com/09spr/cmpt166/lectures/35-patterns.pdf </ref> |
Purpose of Use | Enables the use of two or more unrelated interfaces, together, as one unit. This can be done by converting one (or more) of the interfaces to adapt to the type of interface that is required by the client. thus, adapter pattern acts as a Wrapper, thus, also called, Wrapper Pattern. <ref name=>JAVA DESIGN PATTERNS http://www.allapplabs.com/java_design_patterns/adapter_pattern.htm </ref> | This pattern is used to define and maintain an algorithm directed towards how you want the flow of execution to be. This template method is defined in the parent class and made final, so that all children have to follow the same flow. | Purpose of Structural pattern is to act as a wrapper to make different interfaces ready for the client interface as against that of a Behavioral pattern is to define a common algorithm defining method as final in the parents class to act as a template for all the child classes to decide the flow of control. |
Example | public class SquarePeg {
public void insert(String str) { System.out.println("SquarePeg insert(): " + str); } }
public void insertIntoHole(String msg) { System.out.println("RoundPeg insertIntoHole(): " + msg); } } public class PegAdapter extends SquarePeg { private RoundPeg roundPeg; public PegAdapter(RoundPeg peg) {this.roundPeg = peg;} public void insert(String str) {roundPeg.insertIntoHole(str);} } |
public class Response
public final void import_response() { template_method() { MethodA(); if(int i < 4) MethodB(); else MethodC(); } abstract public MethodA(); abstract public MethodB(); abstract public MethodC(); } public class Feedback_response extends Response { MethodA() { //some definition } MethodB() { //some definition } MethodC() { //some definition } } |
In the template method pattern the Response class is the parent class with a final method import_response() which is the template defining the algorithm with the flow of method calls required. The methods, MethodA(), MethodB() and MethodC() are defined as abstract in the parent class and definitions are provided for these in the child class. Any class that extends Response class now has to follow the same algorithm as described in the method import_response(). |
Comparison with Strategy Design Pattern
Characteristics | Strategy Design Pattern | Template Method Design Pattern | Explanation |
---|---|---|---|
Design Pattern Category | Behavioral Pattern | Behavioral Pattern | In Behavioral patterns, the focus is on communication between objects and what each object does. Thus, both these patterns enable user to define an algorithm of some form which determines the flow of control of the program. <ref name='Behavioral'>Strategy Pattern http://content.gpwiki.org/index.php/Strategy_pattern </ref> |
Purpose of Use | The algorithm defining the flow of control in a Strategy pattern can be changed even after a class that uses that algorithm has been finalized. Thus, the algorithm per say is not final and can be changed. In fact, the algorithm defining function may be declared as part of an interface and left to classes implementing that interface to implement. | This template method is defined in the parent class and made final, so that all children have to follow the same flow. Thus, the algorithm defining flow fo control in this cannot cannot be changed under any circumstances. Once defined it is fixed for all children. | Purpose of behavioral pattern is to define a common algorithm defining the flow of control of the program, to act as a template for all the child classes to decide their flow of control. |
Example | interface myInterface {
int findSum(int x, inty, int z); } class A implements myInterface { public int findSum(int x, int y, int z) { //some definition } class B implements myInterface { public int findSum(int x, int y, int z) { //some definition } |
public class Response
public final void import_response() { template_method() { MethodA(); if(int i < 4) MethodB(); else MethodC(); } abstract public MethodA(); abstract public MethodB(); abstract public MethodC(); } public class Feedback_response extends Response { MethodA() { //some definition } MethodB() { //some definition } MethodC() { //some definition } } |
In the Strategy pattern as described, an interface myInterface has a declaration to the defining algorithm method. All the classes that implement this interface must provide a definition to this method findSum. Thus, each implementing class will provide its own way of defining the flow of control. Thus, this pattern although being a behavioral pattern, is different from template method pattern, in fact almost contrast to it.
In the template method pattern the Response class is the parent class with a final method import_response() which is the template defining the algorithm with the flow of method calls required. The methods, MethodA(), MethodB() and MethodC() are defined as abstract in the parent class and definitions are provided for these in the child class. Any class that extends Response class now has to follow the same algorithm as described in the method import_response(). |
Comparison with Proxy Design Pattern
Characteristics | Proxy Design Pattern | Template Method Design Pattern | Explanation |
---|---|---|---|
Design Pattern Category | Structural Pattern | Behavioral Pattern | In Structural pattern, the focus is on creating ease of design by identifying a simple way to realize relationships between entities. In Behavioral patterns, on the other hand, the focus is on communication between objects and what each object does. Thus, both these patterns enable user to define an algorithm of some form which determines the flow of control of the program. <ref name='Behavioral'>Strategy Pattern http://content.gpwiki.org/index.php/Strategy_pattern </ref> |
Purpose of Use | The algorithm defining the flow of control in a Strategy pattern can be changed even after a class that uses that algorithm has been finalized. Thus, the algorithm per say is not final and can be changed. In fact, the algorithm defining function may be declared as part of an interface and left to classes implementing that interface to implement. | This template method is defined in the parent class and made final, so that all children have to follow the same flow. Thus, the algorithm defining flow of control in this cannot cannot be changed under any circumstances. Once defined it is fixed for all children. | Purpose of behavioral pattern is to define a common algorithm defining the flow of control of the program, to act as a template for all the child classes to decide their flow of control. Purpose of the Proxy pattern is use a less complex object in place of the actual object until such a time that the actual object can be created. The less complex object is known as the proxy for the actual object. |
Example | inteface myInterface {
public abstract void display(); } class classA implements myInterface { private void loadImage() { System.out.println("Loading in classA"); } public void display() { system.out.println("Displaying in classA"); } } class classB implements myInterface { private void loadProxyImage(final Sting FILENAME) { filename = FILENAME; } public void display() { if(image == null) { image = new classA(filename); } image.display(); } } |
public class Response
public final void import_response() { template_method() { MethodA(); if(int i < 4) MethodB(); else MethodC(); } abstract public MethodA(); abstract public MethodB(); abstract public MethodC(); } public class Feedback_response extends Response { MethodA() { //some definition } MethodB() { //some definition } MethodC() { //some definition } } |
In the Strategy pattern as described, an interface myInterface has a declaration to the defining algorithm method. All the classes that implement this interface must provide a definition to this method findSum. Thus, each implementing class will provide its own way of defining the flow of control. Thus, this pattern although being a behavioral pattern, is different from template method pattern, in fact almost contrast to it.
In the template method pattern the Response class is the parent class with a final method import_response() which is the template defining the algorithm with the flow of method calls required. The methods, MethodA(), MethodB() and MethodC() are defined as abstract in the parent class and definitions are provided for these in the child class. Any class that extends Response class now has to follow the same algorithm as described in the method import_response(). |
Conclusion
Behavioral design patterns, generally identify the communication between different objects and classes and how this can be made most efficiently. The behavioral design pattern, Template Method pattern, is one of the most important patterns in certain situations like in cases where we need a static algorithm defined for some purpose. Whenever we do not want the child classes to make a decision about the flow of the algorithm or we do not want the child class interfering with the parents decision, it would be ideal to use this design pattern. It also gives you a very easy way to maintain your code and make changes to it in the future as everything needs to be done only in one place. In conclusion, Template Method pattern can be explained as easily as defining a skeleton of an algorithm in an operation, deferring some steps to sub classes.
See Also
- Behavioral Pattern
- Software Design Pattern
- Adapter Pattern
- Strategy Pattern
- Proxy Pattern
- Non-Virtual Interface
- GRASP
- Program Skeleton
- Algorithm
- Template Method Pattern
- Method Overriding
- Inheritance
- Template Classes in PHP
- Templates
- http://www.avajava.com/tutorials/lessons/template-method-pattern.html
References
<references/>