Today we are going to see one of the design patterns abstract factory. Its one level of abstraction higher than factory pattern.The main use of Abstract Factory Patten is that is isolates the concrete classes which are generated. Do we need the names of actual implemenating classes?
The names of actual implementing classes are not needed to be known at the client side. Because of the isolation, you can change the implementation from one factory to another. This means that the abstract factory returns the factory of classes.
Since being a die hard fan of RajiniKanth, let me get into his style of explaining things with an example. Let us go with an requirement where we are choosing our team for the current project.
[codesyntax lang="java5"]
public abstract class ResourceManager {
public abstract Specs getTeamSize();
public abstract Specs getTeamsManager();
public abstract Specs getTechnology();
}// End of class
[/codesyntax]
This class, as you can see, has three methods all returning different Specs of Resources Needed. They all return a method called Specs . The specification will be different for different types of Projects. Let’s have a look at the class Specs .
[codesyntax lang="java5"]
package creational.abstractfactory;
public class Specs {
public String specification;
public Specs (String specification) {
this.specification = specification;
}
public String getSpecification() {
return specification;
}
}// End of class
[/codesyntax]
And now lets go to the sub-classes of ResourceManager . They are Google, Davita and Yahoo.
[codesyntax lang="java5"]
package creational.abstractfactory;
public class Google extends ResourceManager {
public Specs getTeamSize() {
return new Specs ("25");
}
public Specs getTeamsManager() {
return new Specs ("Vivek");
}
public Specs getTechnology() {
return new Specs ("Java");
}
}// End of class
[/codesyntax]
[codesyntax lang="java5"]
public class Davita extends ResourceManager {
public Specs getTeamSize() {
return new Specs ("30");
}
public Specs getTeamsManager() {
return new Specs ("Vinothbabu");
}
public Specs getTechnology() {
return new Specs ("Flex");
}
}// End of class
[/codesyntax]
[codesyntax lang="java5"]
public class Yahoo extends ResourceManager {
public Specs getTeamSize() {
return new Specs ("10");
}
public Specs getTeamsManager() {
return new Specs ("Padmanaban");
}
public Specs getTechnology() {
return new Specs ("DOT NET");
}
}// End of class
[/codesyntax]
Now let’s have a look at the Abstract factory which returns a factory “ResourceManager ”. We call the class ResourceType.
[codesyntax lang="java5"]
package creational.abstractfactory;
public class ResourceType {
private ResourceManager resm;
public static void main(String[] args) {
ResourceType type = new ResourceType();
//ResourceManager resourceManager = type.getClientName("Google");
System.out.println("Monitor: "+computer.getTeamSize().getSpecification());
System.out.println("RAM: "+computer.getTeamsManager().getSpecification());
System.out.println("Processor: "+computer.getTechnology().getSpecification());
}
public Computer getClientName(String resourceType) {
if (resourceType.equals("Google"))
resm = new Google();
else if(computerType.equals("Davita"))
resm = new Davita();
else if(computerType.equals("Yahoo"))
resm = new Yahoo();
return resm;
}
}// End of class
[/codesyntax]
Conclusion:
Abstract factory pattern centralizes decision of what factory to instantiate. Abstract Factory can be used as an alternative to Facade to hide platform-specific classes.