top of page
Writer's pictureThe Tech Platform

The Factory Design Pattern

Updated: Apr 5, 2023

The Factory design 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. In other words, the Factory pattern provides a way to delegate the object creation responsibility to subclasses.


The Factory pattern consists of two main components: the Factory class and the Product class. The Factory class is responsible for creating objects of the Product class. The Product class defines the interface for the objects that the Factory class creates.


The Factory class has a method that creates objects of the Product class. This method can be overridden by subclasses to create different types of objects. The Factory class can also have other methods that manipulate the created objects.


The Factory pattern is commonly used in situations where multiple types of objects need to be created, and the specific type of object needed is determined at runtime. Some examples of where the Factory pattern might be used include:

  • Creating objects for a game, such as different types of enemies or power-ups

  • Creating objects for a GUI, such as different types of buttons or menus

  • Creating objects for a database, such as different types of database connections or queries


The factory method pattern suggests that you replace direct object construction calls with calls to a factory method. Objects returned by factory methods are called products.


By overriding the factory method in a subclass, we can change the type of product that is being created. The factory method in the base class should have this interface declared as its return type.



Car class implement the Transport interface, which declares a method called deliver(). Each class implements the method differently, the car takes passengers by road and the flight takes them by air.


Depending on client requirements, the ConcreteTransportationFactory class returns car or flight objects.


UML Class Diagram


Implementation Steps:

  1. Define a base class: In this example, we define a base class called Vehicle that will serve as the parent class for all the different types of vehicles we want to create. This class has three properties: make model and year.

  2. Define subclasses: We define two subclasses of the Vehicle class: Car and Truck. Each subclass has its own set of properties and methods that make it unique. For example, the Car class has a num_doors property, while the Truck class has a payload_capacity property.

  3. Create a Factory class: We create a VehicleFactory class that will be responsible for creating objects of the Car and Truck classes. This class has a static method called create_vehicle that takes in four parameters: vehicle_type, make, model, and year. This method uses the vehicle_type parameter to determine what type of vehicle to create.

  4. Implement create_vehicle method: The create_vehicle method is implemented using an if-else block that checks the value of the vehicle_type parameter. If the parameter is "car", the method creates a Car object with the given make, model, and year parameters. If the parameter is "truck", the method creates a Truck object. If the parameter is neither "car" nor "truck", the method raises a ValueError.

  5. Use the Factory class to create objects: In the example usage section, we create a Car object and a Truck object using the create_vehicle method of the VehicleFactory class. We pass in the appropriate parameters to create each object. Once the objects are created, we can access their properties and methods as needed.

Here's a step-by-step guide:


STEP 1: We define a base class called Vehicle.

This class has three properties: make model and year. The __init__ method initializes these properties when a new Vehicle object is created.

class Vehicle:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year

STEP 2: We define a subclass of Vehicles called Cars.

This class inherits the make, model, and year properties from the Vehicle class and adds an additional property called num_doors. The __init__ method calls the __init__ method of the Vehicle class to initialize the make, model, and year properties and then initializes the num_doors property to 4.

class Car(Vehicle):
    def __init__(self, make, model, year):
        super().__init__(make, model, year)
        self.num_doors = 4

STEP 3: We define another subclass of vehicles called trucks.

This class also inherits the make, model, and year properties from the Vehicle class and adds an additional property called payload_capacity. The __init__ method calls the __init__ method of the Vehicle class to initialize the make, model, and year properties and then initializes the payload_capacity property to 2000.

class Truck(Vehicle):
    def __init__(self, make, model, year):
        super().__init__(make, model, year)
        self.payload_capacity = 2000

STEP 4: We define a VehicleFactory class.

This class has a static method called create_vehicle that takes four parameters: vehicle_type, make, model, and year. This method creates a new object of the appropriate type (Car or Truck) based on the value of vehicle_type and returns it. If vehicle_type is not a valid value, the method raises a ValueError.

class VehicleFactory:
    @staticmethoddef create_vehicle(vehicle_type, make, model, year):
        if vehicle_type == "car":
            return Car(make, model, year)
        elif vehicle_type == "truck":
            return Truck(make, model, year)
        else:
            raise ValueError("Invalid vehicle type")

STEP 5: In the example usage section, we create a Car object and a Truck object using the VehicleFactory class. We call the create_vehicle method of the VehicleFactory class, passing in the appropriate vehicle_type ("car" or "truck") as well as the make, model, and year parameters. We then print out some of the properties of each object.

car = VehicleFactory.create_vehicle("car", "Toyota", "Camry", 2022)
print(car.make, car.model, car.year, car.num_doors)

truck = VehicleFactory.create_vehicle("truck", "Ford", "F-150", 2022)
print(truck.make, truck.model, truck.year, truck.payload_capacity)

STEP 6: When we run the code, we see that it correctly creates a Car object with four doors and a Truck object with a payload capacity of 2000.

Toyota Camry 2022 4
Ford F- 150 2022 2000

When To Use Factory Design Pattern?

The Factory design pattern is a creational pattern that is used to create objects without specifying the exact class of object that will be created. Instead, the pattern delegates the responsibility of object creation to a separate class, which is called a factory. The factory class creates objects based on the inputs it receives and returns them to the calling code.


The Factory pattern is commonly used in situations where:

  1. There is a need to create objects of different classes that share a common interface or parent class.

  2. The exact class of object that needs to be created is determined at runtime, based on some input parameter or condition.

  3. The code needs to be flexible and easily maintainable so that new classes can be added to the program without affecting the existing code.

  4. The creation of objects involves complex logic that is best encapsulated in a separate class.

Here are some examples of situations where the Factory pattern can be applied:

  1. When building a GUI application that needs to create different types of widgets, such as buttons, checkboxes, and text boxes, based on user input.

  2. When building a game that needs to create different types of enemies, power-ups, or weapons, based on the level of the game or player progress.

  3. When building a web application that needs to create different types of database connections or data access objects, based on the type of database or the data being accessed.

  4. When building a logging or error handling system that needs to create different types of loggers or error handlers, based on the severity of the error or the type of message being logged.


Benefits of Factory Design Pattern:

  1. Avoid tight coupling between the creator and the concrete products.

  2. Easier to add new types of objects to the program without affecting the existing code.

  3. Implement the single responsibility principle by consolidating the product creation code.

  4. You can introduce new products into the software without breaking existing client code by using the Open/Closed Principle.

  5. It separates the concerns of object creation from other aspects of the program, such as object usage and manipulation. This makes it easier to test and debug the code and can improve the quality of the program.


Conclusion

The Factory pattern is useful in any situation where there is a need to create objects dynamically, based on some input parameters or conditions. By using a factory class to create objects, the code becomes more flexible, easier to maintain, and more extensible, which can save time and effort in the long run.



The Tech Platform

0 comments

Comments


bottom of page