Abstract Factory Pattern

Abstract factory Pattern is a creational pattern that works around a super factory which creates other factories. It is also called as factory of factories.

In abstract factory pattern an interface is responsible for creating a factory of related objects without explicitly specifying their classes. Each generated factory can give the objects as per the Factory Pattern (more detailed – here).

In example below Shape interface is created with concrete classes implementing it. Also AbstractFactory class is created along with ShapeFactory and RoundedShapeFactory classes extending it. Class FactoryProducer is used as factory creator/generator. See the following scheme:

Abstract Factory Pattern UML Diagram

Step 1 : Create an interface Shape

public interface Shape {
void draw();
}

Step 2 : Create concrete classes implementing the same interface

public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
public class RoundedRectangle implements Shape {
@Override
public void draw() {
System.out.println("Inside RoundedRectangle::draw() method.");
}
}
public class RoundedSquare implements Shape {
@Override
public void draw() {
System.out.println("Inside RoundedSquare::draw() method.");
}
}

Step 3 : Create an abstract class to get factories for Normal and Rounded Shape objects

public abstract class AbstractFactory {
public abstract Shape getShape(String shapeType);
}

Step 4 : Create Factory classes extending AbstractFactory to generate object of concrete class based on given information

public class ShapeFactory extends AbstractFactory {
@Override
public Shape getShape(String shapeType){
if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
}else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
}
public class RoundedShapeFactory extends AbstractFactory {
@Override
public Shape getShape(String shapeType){
if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new RoundedRectangle();
}else if(shapeType.equalsIgnoreCase("SQUARE")){
return new RoundedSquare();
}
return null;
}
}

Step 5 : Create a Factory generator/producer class to get factories by passing an information such as Shape

public class FactoryProducer {
public static AbstractFactory getFactory(boolean rounded){
if (rounded) {
return new RoundedShapeFactory();
} else{
return new ShapeFactory();
}
}
}

Step 6 : Use FactoryProducer to get AbstractFactory in order to get factories of concrete classes by passing an information such as type

public class AbstractFactoryPatternDemo {
public static void main(String[] args) {
//get shape factory
AbstractFactory shapeFactory = FactoryProducer.getFactory(false);
//get an object of Shape Rectangle
Shape shape1 = shapeFactory.getShape("RECTANGLE");
//call draw method of Shape Rectangle
shape1.draw();
//get an object of Shape Square
Shape shape2 = shapeFactory.getShape("SQUARE");
//call draw method of Shape Square
shape2.draw();
//get shape factory
AbstractFactory shapeFactory1 = FactoryProducer.getFactory(true);
//get an object of Shape Rectangle
Shape shape3 = shapeFactory1.getShape("RECTANGLE");
//call draw method of Shape Rectangle
shape3.draw();
//get an object of Shape Square
Shape shape4 = shapeFactory1.getShape("SQUARE");
//call draw method of Shape Square
shape4.draw();

}
}

The output will be :

Inside Rectangle::draw() method.
Inside Square::draw() method.
Inside RoundedRectangle::draw() method.
Inside RoundedSquare::draw() method.

Leave a Reply

Your email address will not be published. Required fields are marked *