Abstract FactoryPattern
Previously we learn JAVA - Factory Pattern
The Abstract Factory is known as a creationalpattern - it's used to construct objects such that they can be decoupled fromthe implementing system.
The pattern is best utilized when your systemhas to create multiple families of products or you want to provide a library ofproducts without exposing the implementation details. As you'll have noticed, akey characteristic is that the pattern will decouple the concrete classes fromthe client.
Provides an interface for creating families ofrelated or dependent objects without specifying their concrete classes.
The AbstractFactory class is the one thatdetermines the actual type of the concrete object and creates it, but itreturns an abstract pointer to the concrete object just created.
One of the main benefits of this pattern is that the client is totallydecoupled from the concrete products. Also, new product families can be easilyadded into the system, by just adding in a new type of ConcreteFactory thatimplements AbstractFactory, and creating the specific Product implementations.
Implementingan Example:
We are going to create a Shape and Colorinterfaces and concrete classes implementing these interfaces. We create anabstract factory class AbstractFactory. Factory classes ShapeFactory andColorFactory are defined where each factory extends AbstractFactory. A factorycreator/generator class FactoryProducer is created.
Our demo class uses FactoryProducer to get aAbstractFactory object. It will pass information (CIRCLE / RECTANGLE / SQUAREfor Shape) to AbstractFactory to get the type of object it needs. It alsopasses information (RED / GREEN / BLUE for Color) to AbstractFactory to get the typeof object it needs.
Create aninterface for Shapes.
// Shape.java
public interface Shape{
void draw();
}
Create concreteclasses implementing the same interface.
//Circle.java
public class Circle implements Shape{
@Override
public void draw(){
// TODOAuto-generated method stub
System.out.println("Inside Circle:draw() method.");
}
}
// Square.java
public class Square implements Shape{
@Override
public void draw(){
// TODOAuto-generated method stub
System.out.println("InsideSquare: draw() method.");
}
}
//Rectangle.java
public class Rectangle implements Shape{
@Override
public void draw(){
// TODOAuto-generated method stub
System.out.println("InsideRectangle: draw() method.");
}
}
Create aninterface for Colors.
// Color.java
public interface Color{
void fill();
}
Create concreteclasses implementing the same interface.
//Blue.java
public class Blue implements Color{
@Override
public void fill() {
// TODOAuto-generated method stub
System.out.println("InsideBlue: fill() method.");
}
}
//Green.java
public class Green implements Color{
@Override
public void fill() {
// TODOAuto-generated method stub
System.out.println("InsideGreen: fill() method.");
}
}
//Red.java
public class Red implements Color{
@Override
public void fill() {
// TODOAuto-generated method stub
System.out.println("InsideRed: fill() method.");
}
}
Create anAbstract class to get factories for Color and Shape Objects.
// AbstractFactory
public abstractclass AbstractFactory{
abstractShape getShape(String shape);
abstractColor getColor(String color);
}
Create Factoryclasses extending AbstractFactory to generate object of concrete class based ongiven information.
//ShapeFactory.java
public class ShapeFactory extends AbstractFactory{
@Override
Shape getShape(StringshapeType) {
// TODOAuto-generated method stub
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
}else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
}else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
@Override
Color getColor(Stringcolor) {
// TODOAuto-generated method stub
return null;
}
}
//ColorFactory.java
public class ColorFactory extends AbstractFactory{
@Override
Shape getShape(Stringshape) {
// TODOAuto-generated method stub
return null;
}
@Override
Color getColor(Stringcolor) {
// TODOAuto-generated method stub
if(color == null){
return null;
}
if(color.equalsIgnoreCase("RED")){
return new Red();
}else if(color.equalsIgnoreCase("GREEN")){
return new Green();
}else if(color.equalsIgnoreCase("BLUE")){
return new Blue();
}
return null;
}
}
Create aFactory generator/producer class to get factories by passing an informationsuch as Shape or Color
// FactoryProducer
publicclass FactoryProducer {
public static AbstractFactorygetFactory(String choice){
if(choice.equalsIgnoreCase("SHAPE")){
return new ShapeFactory();
}else if(choice.equalsIgnoreCase("COLOR")){
return new ColorFactory();
}
return null;
}
}
Use theFactoryProducer to get AbstractFactory in order to get factories of concreteclasses by passing an information such as type.
//AbstractFactoryPatternDemo.java
public class AbstractFactoryPatternDemo {
public static void main(String[]args){
//.......getshape factory........
AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
// get anobject of Shape Circle
Shape shape1 =shapeFactory.getShape("CIRCLE");
// call drawmethod of Shape Circle
shape1.draw();
// get anobject of Shape Rectangle
Shape shape2 =shapeFactory.getShape("RECTANGLE");
// call drawmethod of Shape Rectangle
shape2.draw();
// get anobject of Shape Square
Shape shape3 =shapeFactory.getShape("SQUARE");
// call drawmethod of Shape Square
shape3.draw();
//.........getcolor factory..........
AbstractFactorycolorFactory = FactoryProducer.getFactory("COLOR");
//get anobject of Color Red
Color color1 =colorFactory.getColor("RED");
// call fillmethod of Red
color1.fill();
//get anobject of Color Green
Color color2 =colorFactory.getColor("GREEN");
// call fillmethod of Green
color2.fill();
//get anobject of Color Blue
Color color3 =colorFactory.getColor("BLUE");
// call fillmethod of Blue
color3.fill();
}
}
Verify theoutput.

Watch Out for the Downsides:
While the pattern does agreat job of hiding implementation details from the client, there is always achance that the underlying system will need to change. We may have newattributes to our AbstractProduct, or AbstractFactory, which would mean achange to the interface that the client was relying on, thus breaking the API.
Leave a Comment