Creational Design Pattern
![](https://codelido.com/assets/files/2022-12-17/1671309238-9713-single-ton-design-pattern-3.jpg)
Definition
The abstract factory pattern is similar to the factory pattern and is a factory of factories. If you are familiar with the factory design pattern in Java, you will notice that we have a single factory class that returns the different subclasses based on the input provided and the factory class uses if-else or switch statements to achieve this. In the abstract factory pattern, we get rid of if-else block and have a factory class for each subclass and then an abstract factory class that will return the subclass based on the input factory class.
Characteristics
- Abstract Factory pattern is a creational design pattern.
- It provides an interface for creating related objects without specifying their concrete classes.
- The Abstract Factory pattern is also referred to as a factory of factories.
- It provides an abstract level of interface to create families of related objects.
- This pattern is useful when a system needs to be independent of how its objects are created and composed.
- Abstract Factory pattern makes it possible to interchange concrete implementations without changing the code that uses them.
- It also helps to avoid tight coupling between objects and classes.
- Abstract Factory pattern also helps to create objects that follow a general pattern.
- The Abstract Factory pattern is used in Java to provide a layer of abstraction over concrete implementations of objects.
UML Diagram
![](https://codelido.com/assets/files/2022-12-17/1671309345-285917-image.png)
Code
public interface Shape {
void draw();
}
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.
");
}
}
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 abstract class AbstractFactory {
abstract Shape getShape(String shapeType);
}
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;
}
}
public class FactoryProducer {
public static AbstractFactory getFactory(boolean rounded) {
if (rounded) {
return new RoundedShapeFactory();
} else {
return new ShapeFactory();
}
}
}
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();
}
}
Output
Inside Rectangle::draw() method.
Inside Square::draw() method.
Inside RoundedRectangle::draw() method.
Inside RoundedSquare::draw() method.
Advantages
- It provides a way to encapsulate a group of individual factories that have a common theme.
- It promotes the loose coupling of objects by making them independent of their concrete classes.
- Abstract Factory pattern provides a way to replace implementations without changing the interface of the factories.
- It simplifies the system architecture by localizing the responsibility of creating objects.
Disadvantages
- It can be difficult to extend the abstract factory classes to produce new types of products due to the complexity of the code.
- It can be difficult to maintain and modify the code if the number of products increases.
- It requires a lot of code to implement the pattern which can lead to a bloated codebase.