Thursday, May 1, 2014

Factory Design Pattern

What is the most preferred way of creating an object in Java? no prizes for guessing :-) The answer is simple, using a new operator right? But what if i need to change the way an object is constructed and this object is created using new operation in lot of classes.I need to change in all classes right?

Well, if you are not using any dependency injection frameworks like Spring, its better to use factory pattern (also known as factory method pattern)for constructing objects.

Its a creational design pattern.A factory is a java class which encapsulate the object creation.The composing classes doesn't know how the objects created.A factory class instantiates and returns a particular type of object based on the data passed to the factory.




Lets create a abstract class Account which declares two methods deposit and withdraw.

Account.java

package ramesh.designPatterns;  
 public abstract class Account {  
      public abstract long deposit(long depositAmount);  
      public abstract long withdraw(long withdrawAmount);  
 }  

We have two concrete implementations of Account, named SavingsAccount,java and CurrentAccount.java

package ramesh.designPatterns;  
 public class SavingsAccount extends Account {  
      public long deposit(long depositAmount) {  
           System.out.println("Inside Savings Account's deposit method");  
           long balance=1000;  
           if (depositAmount < 0) {  
                System.out.print("Invalid Amount!");  
           }  
           balance = balance + depositAmount;  
           System.out.println("Current Balance is "+balance);  
           return balance;  
      }  
      @Override  
      public long withdraw(long withdrawAmount) {  
           System.out.println("Inside Savings Account's withdraw method");  
           long balance =30000;  
           System.out.println("Your Balance is: " + balance);  
           if (withdrawAmount > balance) {  
                System.out.println("You do not have a sufficient balance to withdraw this amount!");  
           }  
           balance=balance-withdrawAmount;  
           return balance;  
      }  
 }  


package ramesh.designPatterns;  
 public class CurrentAccount extends Account {  
      public long deposit(long depositAmount) {  
           System.out.println("Inside Current Account's deposit method");  
           long balance=1000;  
           if (depositAmount < 0) {  
                System.out.print("Invalid Amount!");  
           }  
           balance = balance + depositAmount;  
           System.out.println("Current Balance is "+balance);  
           return balance;  
      }  
      @Override  
      public long withdraw(long withdrawAmount) {  
           System.out.println("Inside Current Account's withdraw method");  
           long balance =30000;  
           System.out.println("Your Balance is: " + balance);  
           if (withdrawAmount > balance) {  
                System.out.println("You do not have a sufficient balance to withdraw this amount!");  
           }  
           balance=balance-withdrawAmount;  
           return balance;  
      }  
 }  



Now create a AccountFactory which returns either of these accounts based on our requirement.

AccountFactory.java

package ramesh.designPatterns;  
 public class AccountFactory {  
      Account account;  
      public Account getAccount(String accountType) {  
           if (accountType.equals("savings")) {  
                account = new SavingsAccount();  
           } else if (accountType.equals("current")) {  
                account = new CurrentAccount();  
           }  
           return account;  
      }  
 }  

Now test the factory whether its returning the desired object.

MainApp.java

package ramesh.designPatterns;  
 public class MainApp {  
      /**  
       * @param args  
       */  
      public static void main(String[] args) {  
           AccountFactory factory = new AccountFactory();  
           Account account = factory.getAccount("savings");  
           account.deposit(2000);  
      }  
 }  

Here we requested to return the savings account object and we can confirm that we got the savings account object by seeing the output.

Output:

Inside Savings Account's deposit method
Current Balance is 3000

As you see the advantage of factory which decouple the creation of objects from composing class there is a disadvantages also.

1) Factory class encapsulate the creation of similar objects.So if you need different objects you need to create different factories.
2) The factory should be used for similar type of objects. If the classes doesn't extend common base class or interface they can not be used in a factory design template.

Examples of Factory pattern in Java API

java.util.Calendar#getInstance() 
java.util.ResourceBundle#getBundle() 
java.text.NumberFormat#getInstance() 
java.nio.charset.Charset#forName() 

That's all about Factory design pattern in Java.

Thanks for visiting my blog...