Sunday, 2 January 2011

Factory Design Pattern

Factory pattern is one of the Creational Patterns.
Consider the following EmployeeFactory class which has a method called getEmployee (This method takes two arguments employeeType and employeeName and based on that it creates and returns appropriate Employee class.):


package oops.factory.pattern;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
public class EmployeeFactory {
private static Map employeeTypesMap = new HashMap();
static {
employeeTypesMap.put(Employee.SOFTWARE_ENGINEER, Developer.class);
employeeTypesMap.put(Employee.MANAGER, Manager.class);
employeeTypesMap.put(Employee.ARCHITECT, Architect.class);
}
public static Employee getEmployee(String employeeType, String employeeName) throws EmployeeCreationException{
Class class1 = employeeTypesMap.get(employeeType);
Constructor constructor;
try {
constructor = class1.getConstructor(String.class);
return (Employee)constructor.newInstance(employeeName);
} catch (SecurityException e) {
throw new EmployeeCreationException(e);
} catch (NoSuchMethodException e) {
throw new EmployeeCreationException(e);
}catch (IllegalArgumentException e) {
throw new EmployeeCreationException(e);
} catch (InstantiationException e) {
throw new EmployeeCreationException(e);
} catch (IllegalAccessException e) {
throw new EmployeeCreationException(e);
} catch (InvocationTargetException e) {
throw new EmployeeCreationException(e);
}
}
public static void main(String[] strAr){
Employee emp = null;
try {
emp = EmployeeFactory.getEmployee(Employee.SOFTWARE_ENGINEER, "Ranjan Kumar");
} catch (EmployeeCreationException e) {
e.printStackTrace();
}
if(emp instanceof Developer)
System.out.println("Developer found!!!");
}
}



package oops.factory.pattern;
public interface Employee {
//By default interface fields are public static and final. Hence no need to explicitely declare it with these keywords.
String SOFTWARE_ENGINEER = "Software Engineer";
String LEVEL_SE = "SE Level";
String MANAGER = "Manager";
String LEVEL_MANAGER = "Manager Level";
String ARCHITECT = "Architect";
String LEVEL_ARCHITECT = "Architect";
//By default interface methods are public and abstract. Hence no need to explicitely declare it like that.
String getName();
String getDesignation();
String getLevel();
}



package oops.factory.pattern;
public class Developer implements Employee {
private String name;
public Developer(String name) {
this.name = name;
}
@Override
public String getDesignation() {
return SOFTWARE_ENGINEER;
}
@Override
public String getLevel() {
return LEVEL_SE;
}
@Override
public String getName() {
return name;
}
}



package oops.factory.pattern;
public class Manager implements Employee {
private String name;
public Manager(String name) {
this.name = name;
}
@Override
public String getDesignation() {
return MANAGER;
}
@Override
public String getLevel() {
return LEVEL_MANAGER;
}
@Override
public String getName() {
return name;
}
}



package oops.factory.pattern;
public class Architect extends Developer {
// You will have to define this constructor. Don't you Agree?
public Architect(String name) {
super(name);//Cool
}
@Override
public String getDesignation() {
return ARCHITECT;
}
@Override
public String getLevel() {
return LEVEL_ARCHITECT;
}
}


If you understood the classes defined above, you understood factory design pattern :). This pattern is very much userful when you have objects having some of the properties in common. So user can instantiate classes based on the data he has without knowing which class he needs to instantiate. In the example explained above user/caller (main method) need not know about what a Developer class is etc etc.

No comments:

Post a Comment