Wednesday, June 4, 2008

Template Pattern

Template pattern is all about encapsulating algorithm or process. It defines a skeleton of an algorithm with some abstract methods, which allows subclasses to redefine certain steps with out changing the algorithm structure. These abstract methods allow subclasses to be a part of the algorithm so that the pre defined algorithm can be reused.

Why Template:

  1. Encapsulates algorithm or process, So that it can be reused.
  2. Allows sub classes to be a part of the process, so this pattern is often seen in different frameworks.

How to use Template:

It is a common scenario that we need to authenticate and authorize an user before letting him to execute some secured facility. The user only gets to call the method if he is valid. Here the process sequence is the same. First check if he is valid and then let him execute the method depending on validation. We can encapsulate the process and create "hook up" or "plug in" abstract methods. The client sub class can implement the abstract methods and become part of the process. Here what varies is the logic to verify the user and eventually the logic to execute. So we let the client sub classes to define that part by implementing the abstract methods.

Class Diagram :

Template Pattern

Java Code :

AbstractPage.cs
public abstract class AbstractPage {

   private String userName;

   public void setUserName(String userName) {
       this.userName = userName;
   }

   public void run() {
       //a simple process for validation
       //which is encapsulated in the template class
       if (isValid(userName)) {
           execute();
       }
   }
   //abstract hook up methods which is defined in sub classes

   public abstract boolean isValid(String name);

   public abstract void execute();
}
Page.cs 
public class Page extends AbstractPage {

   public boolean isValid(String name) {       //my code to validate user is in here      
       return true;//just a dummy return  
   }

   public void execute() {
       //my code to execute is here  
   }
}
TestTemplate.cs 
class TestTemplate {

   private AbstractPage abstractPage;

   public TestTemplate(AbstractPage abstractPage) {
       this.abstractPage = abstractPage;
   }

   public void runProcess() {
       abstractPage.execute();
   }
}

Object Oriented Principals used in Template : 

  1. The Hollywood principle(don't call us, we'll call you)
  2. Code to interface or abstraction not to concrete class.
  3. High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions.[Dependency Inversion Principal]

We see the Hollywood principle in this pattern because the client sub class is being used by the template class. The sub class is being called and becoming part of the process. And eventually the control belongs to the template class.

The template class is dependent on abstract methods which is later implemented by client sub classes. Template do not have any idea on concrete implementation, it is coded to abstraction. 

Dependency Inversion Principal is often used in deferent design patterns. In Template Pattern the high level class is the template class and the implementation is lower level class. Template class is not directly dependent on sub classes rather it is dependent on abstract methods or abstraction. And the client sub class is also dependent on the abstract template class. 

Observation : 

Object oriented pattern is all about encapsulation. Template is a trick to encapsulate process or algorithm, so that the process can be re used, which is achieved by inheritance. But one object oriented principal states that, "prefer composition over inheritance". In template we are using inheritance, which can be replaced by Strategy pattern. A template needs some feed or it needs to provide some hook up, which are achieved by abstract methods. These methods can be interfaced out of the abstract class of Template and convert inheritance in to composition. But it is always a design choice and context dependent decision.

Template is widely used in frameworks for it's ability to allow others to become a part of the system. Similar implementation is seen in Spring controllers, where the frameworks has the control and client controllers are plugged in the system by instantiating the abstract controllers. 

References : 

http://sourcemaking.com/design_patterns/template_method

Monday, June 2, 2008

Strategy Pattern

Strategy is one of the elegant design patterns which uses the polymorphism feature of object oriented language. This pattern allows you to change the strategy of how the class will behave at run time, so that your code can keep up with change.

Why "Strategy" :

  1. Can change how the class will behave at run time
  2. Makes your code reusable and extendable

First let's make a simple scenario that is appropriate for us to use Strategy Pattern. Suppose you need to write a simple copy function that copies a file from one place to another. The problem is that your boss wants to support different OS platform. You can say why need strategy I can write a simple code like,

public class FileCopier {

   public void copyFile(File source, File destination) {
       if (platform == windows) {
           copyWindowFile(source, destination);
       } else if (platform == linux) {
           copyLinuxFile(source, destination);
       }
   }

   public void copyWindowFile(File source, File destination) {
       //here is your windows copy code 
   }

   public void copyLinuxFile(File source, File destination) {
       //here is your Linux copy code 
   }
}

Now what if your boss tells you to add support for Mac OS. Then you will have to change the FileCopier class and re-test it. This surely will not make your boss happy as FileCopier is a very important class and people don't want it to change. One other thing is that change in FileCopier class to add support for Mac will also impact the software for other platforms, which is not desired.

One of the key feature of using real good object orientation is that it reduces change. And adding endless if-else block will make your code lengthy and fragile and you will also face the wrath of the other programmer who might have to change your code.

How to use "Strategy" :

Class Diagram:

Strategy

Java Code:

IFileCopier.java:
public interface IFileCopier {
   void copyFile(File source, File destination);
}
WindowsFileCopier.java
public class WindowsFileCopier implements IFileCopier {

   public void copyFile(File source, File destination) {
       //copy file in Window machine
   }
}
LinuxFileCopier.java
public class LinuxFileCopier implements IFileCopier {

   public void copyFile(File source, File destination) {
       //copy file in Linux machine
   }
}

When IFileCopier is used in any context, it is coded using the interface IFileCopier. So it works for all the implementations of IFileCopier. When you will pass an instance of LinuxFileCopier it will have the behavior of copying file in Linux and an instance of WindowsFileCopier it will have the behavior of copying file in Windows. Now you can create another implementation of IFileCopier and pass the new implementation. As long as your implementation is OK the existing code will be OK : ). So here you are actually reducing the amount of change in existing code. So the amount of test is reduced and you can cope up with the change faster.

Object Oriented Principals used in Strategy :

1. Code to interface or abstraction not to concrete class. 2. High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions.[Dependency Inversion Principal] 3. Single Responsibility Principal(SRP) 4. Encapsulate what varies from what stays the same 

We see the first principal in Context class as there we did code to interface(IFileCopier). Context is high level class and WindowsFileCopier or LinuxFileCopier is lower level class as Context uses them. But Context is actually dependent on an interface not to a concretion. So Strategy follows Dependency Inversion Principal. Single Responsibility Principal states that, "a class should have only one reason to change". In other words a class should do one thing and do it very well. Here we used this principal as we separated the OS dependant logic to separate class. So change in one part will not effect change in other parts. One other important thing is that we should identify parts that varies in a system. So that we could encapsulate what varies from what stays the same. Here we encapsulated the behavior to copy files, so that it could give us flexibility to re use it to support different OS platform. This will allow us to minimize change and maximize flexibility.

References:

http://sourcemaking.com/design_patterns/strategy http://www.exciton.cs.rice.edu/JavaResources/DesignPatterns/StrategyPattern.htm http://en.wikipedia.org/wiki/Strategy_pattern