Factory Design Pattern:
This pattern is to create the number of objects as per
request with the help of polymorphism and inheritance (super-class-sub-class). Creation
of object is generally getting decided using String pattern. This pattern
allows creating the object without exposing the instantiation logic.
Let us see the example below for
Shoes factory which is able to create n number of objects as per request:-
1st Approach:-
public class MyShoesFactory {
private MyShoesFactory(){}
public static Shoes
createShoesObject(String shoesType){
if("Sports".equals(shoesType)){
return new SportShoes();
}
if("Formal".equals(shoesType)){
return new SportShoes();
}
if("Casual".equals(shoesType)){
return new SportShoes();
}
return null;
}
}
interface Shoes{
}
class SportShoes implements Shoes{
//code here
}
class FormalShoes implements Shoes{
//code here
}
class CasualShoes implements Shoes{
//code here
}
2nd Approach:-
Better design, no need to change
the MyShoesFactory class,
used reflection and tried to keep open/closed principal implemented nicely.
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
public class MyShoesFactory {
private MyShoesFactory(){}
@SuppressWarnings("unchecked")
private static
HashMap<String, Class> registeredShoesMap = new HashMap<String,
Class>();
static{
MyShoesFactory.registerShoes("Formal", FormalShoes.class);
MyShoesFactory.registerShoes("Casual", CasualShoes.class);
MyShoesFactory.registerShoes("Sport", SportShoes.class);
}
@SuppressWarnings("unchecked")
public static void registerShoes(String shoesId, Class
shoesClass) {
registeredShoesMap.put(shoesId, shoesClass);
}
@SuppressWarnings("unchecked")
public static Shoes
createShoesObject(String shoesID) throws SecurityException,
NoSuchMethodException,
IllegalArgumentException, InstantiationException, IllegalAccessException,
InvocationTargetException {
Class shoesClass = (Class)registeredShoesMap.get(shoesID);
Constructor shoesConstructor =
shoesClass.getDeclaredConstructor();
return (Shoes)shoesConstructor.newInstance(new Object[] { });
}
}
interface Shoes{
public void displayMessage();
}
class SportShoes implements Shoes{
//code here
public void displayMessage(){
System.out.println(" I am a
Sport Shoes ... ");
}
}
class FormalShoes implements Shoes{
//code here
public void displayMessage(){
System.out.println(" I am a
Formal Shoes ... ");
}
}
class CasualShoes implements Shoes{
//code here
public void displayMessage(){
System.out.println(" I am a
Casual Shoes ... ");
}
}
import java.lang.reflect.InvocationTargetException;
public class Client {
public static void main(String[] args) throws SecurityException, IllegalArgumentException,
NoSuchMethodException,
InstantiationException, IllegalAccessException, InvocationTargetException {
Shoes formalShoes = MyShoesFactory.createShoesObject("Formal");
Shoes casualShoes = MyShoesFactory.createShoesObject("Casual");
formalShoes.displayMessage();
casualShoes.displayMessage();
}
}
Output:
I am a Formal Shoes ...
I am a Casual Shoes ...
If any new type
of shoes comes in future (say FashionShoes) no need to modify the factory class
just use the below snippet in Client class to register FashionShoes class with
Factory:
MyShoesFactory.registerShoes("Fashion", FashionShoes.class);
Use:-
Suppose if we are developing an application using Postgres database, but in
future may need to change database to oracle, and then need to modify all our
code, if not properly designed. One way to do this in better way is factory
design pattern. A class implementing factory design pattern takes care for this
and lessen the burden. Switching from database server won’t bother at all. We
just need to make some small changes in our configuration file.
Note:-
Factory design pattern should be used
for a family of objects. If the classes don’t extend/implement common base
class/interface they can not be used.
No comments:
Post a Comment