Introduction
The Factory pattern is a creational design pattern that provides an interface for creating objects in a superclass, but allows subclasses to alter the type of objects that will be created. It abstracts the instantiation process, letting the client code rely on a common interface rather than concrete implementations, which promotes flexibility and maintainability.
Purpose
Creates objects without specifying the exact class of the object that will be created.
Use Cases
Object creation where subclasses decide which class to instantiate.
1from abc import ABC, abstractmethod2 3# Abstract Product4class Shape(ABC):5 @abstractmethod6 def draw(self):7 pass8 9# Concrete Products10class Circle(Shape):11 def draw(self):12 return "Drawing a Circle"13 14class Square(Shape):15 def draw(self):16 return "Drawing a Square"17 18# Factory19class ShapeFactory:20 @staticmethod21 def get_shape(shape_type):22 if shape_type == "circle":23 return Circle()24 elif shape_type == "square":25 return Square()26 else:27 raise ValueError("Unknown shape type")28 29# Usage30factory = ShapeFactory()31shape1 = factory.get_shape("circle")32shape2 = factory.get_shape("square")33print(shape1.draw()) # Drawing a Circle34print(shape2.draw()) # Drawing a Square1// Abstract Product is not enforced in JS, but we define concrete products2class Circle {3 draw() {4 return "Drawing a Circle";5 }6}7 8class Square {9 draw() {10 return "Drawing a Square";11 }12}13 14// Factory15class ShapeFactory {16 static getShape(shapeType) {17 if (shapeType === "circle") {18 return new Circle();19 } else if (shapeType === "square") {20 return new Square();21 } else {22 throw new Error("Unknown shape type");23 }24 }25}26 27// Usage28const shape1 = ShapeFactory.getShape("circle");29const shape2 = ShapeFactory.getShape("square");30console.log(shape1.draw()); // Drawing a Circle31console.log(shape2.draw()); // Drawing a Square1// Abstract Product2abstract class Shape {3 String draw();4}5 6// Concrete Products7class Circle implements Shape {8 9 String draw() => "Drawing a Circle";10}11 12class Square implements Shape {13 14 String draw() => "Drawing a Square";15}16 17// Factory18class ShapeFactory {19 static Shape getShape(String shapeType) {20 if (shapeType == "circle") {21 return Circle();22 } else if (shapeType == "square") {23 return Square();24 } else {25 throw ArgumentError("Unknown shape type");26 }27 }28}29 30// Usage31void main() {32 var shape1 = ShapeFactory.getShape("circle");33 var shape2 = ShapeFactory.getShape("square");34 print(shape1.draw()); // Drawing a Circle35 print(shape2.draw()); // Drawing a Square36}1# Abstract Product is not enforced in Ruby, but we define concrete products2class Circle3 def draw4 "Drawing a Circle"5 end6end7 8class Square9 def draw10 "Drawing a Square"11 end12end13 14# Factory15class ShapeFactory16 def self.get_shape(shape_type)17 case shape_type18 when "circle"19 Circle.new20 when "square"21 Square.new22 else23 raise "Unknown shape type"24 end25 end26end27 28# Usage29shape1 = ShapeFactory.get_shape("circle")30shape2 = ShapeFactory.get_shape("square")31puts shape1.draw # Drawing a Circle32puts shape2.draw # Drawing a SquareConclusion
The Factory pattern is useful when your code needs to create objects dynamically without hard-coding their concrete classes. It simplifies object creation, encourages loose coupling, and makes it easier to introduce new types of objects or modify creation logic without affecting the client code. Common use cases include creating different shapes, database connections, or user interface components based on configuration or runtime conditions.