Sunday 18 May 2014

AbstractFactory Design Pattern



AbstractFactory Design Pattern:
The essence of the Abstract Factory Pattern is to "Provide an interface for creating families of related or dependent objects without specifying their concrete classes".
Let us see the example as below:

interface IKidsShoes{

      public void displayMessage();
}

class KidsSportShoes implements IKidsShoes{

      //code here
      public void displayMessage(){
            System.out.println(" I am a Kids Sport Shoes ... ");
      }
}

class KidsFormalShoes implements IKidsShoes{

      //code here
      public void displayMessage(){
            System.out.println(" I am a Kids Formal Shoes ... ");
      }
}

class KidsCasualShoes implements IKidsShoes{

      //code here
      public void displayMessage(){
            System.out.println(" I am a Kids Casual Shoes ... ");
      }
}


/************************************************/

interface IMensShoes{

      public void displayMessage();
}

class MensSportShoes implements IMensShoes{

      //code here
      public void displayMessage(){
            System.out.println(" I am a Mens Sport Shoes ... ");
      }
}

class MensFormalShoes implements IMensShoes{

      //code here
      public void displayMessage(){
            System.out.println(" I am a Mens Formal Shoes ... ");
      }
}

class MensCasualShoes implements IMensShoes{

      //code here
      public void displayMessage(){
            System.out.println(" I am a Mens Casual Shoes ... ");
      }
}

/*****************************************************/

interface IWomensShoes{

      public void displayMessage();
}

class WomensSportShoes implements IWomensShoes{

      //code here
      public void displayMessage(){
            System.out.println(" I am a Womens Sport Shoes ... ");
      }
}

class WomensFormalShoes implements IWomensShoes{

      //code here
      public void displayMessage(){
            System.out.println(" I am a Womens Formal Shoes ... ");
      }
}

class WomensCasualShoes implements IWomensShoes{

      //code here
      public void displayMessage(){
            System.out.println(" I am a Womens Casual Shoes ... ");
      }
}


import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
public abstract class AbstractShoesFactory{

      @SuppressWarnings("unchecked")
      private static HashMap<String, Class> registeredFactory = new HashMap<String, Class>();    

      static{
            registerFactory("KidsShoes", KidsShoesFactory.class);
            registerFactory("MensShoes", MensShoesFactory.class);
            registerFactory("WomensShoes", WomensShoesFactory.class);
      }

      @SuppressWarnings("unchecked")
      public static void registerFactory(String factoryId, Class factoryClass)     {
            registeredFactory.put(factoryId, factoryClass);
      }    

      @SuppressWarnings("unchecked")
      public static AbstractShoesFactory createFactory(String factoryId) throws SecurityException,
      NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException      {

            Class factoryClass = (Class)registeredFactory.get(factoryId);     
            Constructor factoryConstructor = factoryClass.getDeclaredConstructor();   
            factoryConstructor.setAccessible(true);
            return (AbstractShoesFactory) factoryConstructor.newInstance(new Object[] { });    
      }
     
      @SuppressWarnings("unchecked")
      public abstract void registerShoes(String shoesId, Class shoesClass);
      public abstract Object createShoesObject(String shoesID) throws SecurityException,
            NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException;
}


import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
class KidsShoesFactory extends AbstractShoesFactory{

      private KidsShoesFactory(){}

      @SuppressWarnings("unchecked")
      private static HashMap<String, Class> registeredKidsShoesMap = new HashMap<String, Class>();    
     
      private void init(){
            registerShoes("Formal", KidsFormalShoes.class);
            registerShoes("Casual", KidsCasualShoes.class);
            registerShoes("Sport", KidsSportShoes.class);
      }

      @SuppressWarnings("unchecked")
      public void registerShoes(String shoesId, Class shoesClass) {
            registeredKidsShoesMap.put(shoesId, shoesClass);     
      }    

      @SuppressWarnings("unchecked")
      public IKidsShoes createShoesObject(String shoesID) throws SecurityException,
      NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException      {

            init();
           
            Class shoesClass = (Class)registeredKidsShoesMap.get(shoesID);     
            Constructor shoesConstructor = shoesClass.getDeclaredConstructor();     
            return (IKidsShoes)shoesConstructor.newInstance(new Object[] { });  
      }
}

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
class MensShoesFactory extends AbstractShoesFactory{

      private MensShoesFactory(){}

      @SuppressWarnings("unchecked")
      private static HashMap<String, Class> registeredMensShoesMap = new HashMap<String, Class>();    
     
      private void init(){
            registerShoes("Formal", MensFormalShoes.class);
            registerShoes("Casual", MensCasualShoes.class);
            registerShoes("Sport", MensSportShoes.class);
      }

      @SuppressWarnings("unchecked")
      public void registerShoes(String shoesId, Class shoesClass) {
            registeredMensShoesMap.put(shoesId, shoesClass);     
      }    

      @SuppressWarnings("unchecked")
      public IMensShoes createShoesObject(String shoesID) throws SecurityException,
      NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException      {

            init();
           
            Class shoesClass = (Class)registeredMensShoesMap.get(shoesID);     
            Constructor shoesConstructor = shoesClass.getDeclaredConstructor();     
            return (IMensShoes)shoesConstructor.newInstance(new Object[] { });  
      }
}


import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
class WomensShoesFactory extends AbstractShoesFactory{
     
      private WomensShoesFactory(){}

      @SuppressWarnings("unchecked")
      private static HashMap<String, Class> registeredWomensShoesMap = new HashMap<String, Class>();    
     
      private void init(){
            registerShoes("Formal", WomensFormalShoes.class);
            registerShoes("Casual", WomensCasualShoes.class);
            registerShoes("Sport", WomensSportShoes.class);
      }

      @SuppressWarnings("unchecked")
      public void registerShoes(String shoesId, Class shoesClass) {
            registeredWomensShoesMap.put(shoesId, shoesClass);   
      }    

      @SuppressWarnings("unchecked")
      public IWomensShoes createShoesObject(String shoesID) throws SecurityException,
      NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException      {
           
            init();

            Class shoesClass = (Class)registeredWomensShoesMap.get(shoesID);  
            Constructor shoesConstructor = shoesClass.getDeclaredConstructor();     
            return (IWomensShoes)shoesConstructor.newInstance(new Object[] { });
      }
}


import java.lang.reflect.InvocationTargetException;

public class Client{

      public static void main(String args[]) throws SecurityException, IllegalArgumentException, NoSuchMethodException,
            InstantiationException, IllegalAccessException, InvocationTargetException{
           
            /** Getting KidsShoes factory 1st and then asking to factory for Formal KidsShoes Object **/
            AbstractShoesFactory kidsShoesfactory = AbstractShoesFactory.createFactory("KidsShoes");
            IKidsShoes kidsShoes = (IKidsShoes) kidsShoesfactory.createShoesObject("Formal");
            kidsShoes.displayMessage();
           
            /** Getting MensShoes factory 1st and then asking to factory for Formal MensShoes Object **/
            AbstractShoesFactory mensShoesfactory = AbstractShoesFactory.createFactory("MensShoes");
            IMensShoes mensShoes = (IMensShoes) mensShoesfactory.createShoesObject("Formal");
            mensShoes.displayMessage();
           
            /** Getting WomensShoes factory 1st and then asking to factory for Formal WomensShoes Object **/
            AbstractShoesFactory womensShoesfactory = AbstractShoesFactory.createFactory("WomensShoes");
            IWomensShoes womensShoes = (IWomensShoes) womensShoesfactory.createShoesObject("Formal");
            womensShoes.displayMessage();
      }
}

Output:-
 I am a Kids Formal Shoes ...
 I am a Mens Formal Shoes ...
 I am a Womens Formal Shoes ...


Note:-
i)      The system should be configured to work with multiple families of products.
ii)     An application usually needs only one instance of the Factory class per family. This means that it is best to implement as a Singleton.

No comments:

Post a Comment