The Factory design pattern is a creational design pattern that provides an interface for creating instances of a class, with its subclasses deciding which class to instantiate. This pattern allows a class to delegate the responsibility of instantiating its objects to its subclasses.
Creator Interface or Abstract Class: This defines the factory method that must be implemented by the concrete factories. It declares the method for creating an object, which will be implemented by the subclasses.
Concrete Creators: These are subclasses that implement the factory method to create instances of the desired type.
Product: This is the interface or abstract class that represents the product to be created by the factory.
Concrete Products: These are the implementations of the product interface, created by the concrete factories.
Separation of Concerns: The creation of objects is centralized in one place, providing a clear separation between the creation and usage of objects.
Flexibility: The client code remains unaware of the specific classes being instantiated, allowing for easy swapping of implementations.
Easy Maintenance: As the object creation logic is centralized, any changes to the creation process can be easily managed within the factory.
Let’s illustrate the Factory design pattern, which implements a factory to create different types of shapes.
package Product;
public interface Shape {
public void draw();
}
package Product;
public class Circle implements Shape{
@Override
public void draw() {
System.out.println("Drawing a circle...");
}
}
package Product;
import Product.Shape;
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Drawing a square...");
}
}
package Factory;
import Product.Shape;
public interface ShapeFactory {
Shape createShape();
}
package Factory;
import Product.Circle;
import Product.Shape;
public class CircleFactory implements ShapeFactory{
@Override
public Shape createShape() {
return new Circle();
}
}
package Factory;
import Product.Shape;
import Product.Square;
public class SquareFactory implements ShapeFactory{
@Override
public Shape createShape() {
return new Square();
}
}
import Factory.CircleFactory;
import Factory.ShapeFactory;
import Factory.SquareFactory;
import Product.Shape;
public class FactoryPattern {
public static void main(String[] args) {
ShapeFactory squareFactory = new SquareFactory();
Shape square = squareFactory.createShape();
square.draw();
ShapeFactory circleFactory = new CircleFactory();
Shape circle = circleFactory.createShape();
circle.draw();
}
}
Drawing a square…
Drawing a circle…
In this example, we have a Shape
interface representing the product, with Circle
and Square
as concrete implementations. We then have a ShapeFactory
interface representing the creator, with CircleFactory
and SquareFactory
as concrete creator implementations. The client code demonstrates how to use these factories to create and draw shapes.