Creational Design Patterns: Factory Method
Purpose
The Factory Method is a design pattern that allows you to create objects without specifying the exact class. Instead of calling a constructor, you delegate object instantiation to a factory method. This decouples the client code from the concrete classes, increasing the system’s flexibility and scalability.
Explanation
In the Factory Method pattern, a class defines a method (the factory method) that subclasses can override to create objects of various types. The primary advantage of this pattern is that it allows you to follow the Open/Closed Principle: your code is open for extension but closed for modification. By introducing a factory method, you can add new types of objects without changing the code that uses them.
Ruby Example: Vehicle Factory
Let’s consider an example where we want to create different types of vehicles—Car
, Truck
, and Motorcycle
. We can use the Factory Method pattern to create these vehicle objects.
Step 1: Define the Product Interface
First, we define a Vehicle
as base class(or interface or abstract class in other languages, but in Ruby, we’ll use a base class with a method that subclasses need to implement).
1
2
3
4
5
class Vehicle
def drive
raise NotImplementedError, "This method must be implemented in a subclass"
end
end
Step 2: Create Concrete Products
Next, we define the concrete classes that inherit from Vehicle
. Each class will override the drive
method.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Car < Vehicle
def drive
puts "Driving a car!"
end
end
class Truck < Vehicle
def drive
puts "Driving a truck!"
end
end
class Motorcycle < Vehicle
def drive
puts "Riding a motorcycle!"
end
end
Step 3: Create the Factory Method
Now, we define a factory class with a factory method that will be responsible for creating instances of Vehicle
. This method can be overridden in subclasses if needed.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class VehicleFactory
def self.create(type)
case type
when :car
Car.new
when :truck
Truck.new
when :motorcycle
Motorcycle.new
else
raise "Unknown vehicle type: #{type}"
end
end
end
Step 4: Using the Factory Method
Finally, we use the VehicleFactory
to create vehicles without knowing the details of the class instantiation.
1
2
3
4
5
6
7
8
9
10
11
vehical_car = VehicleFactory.create(:car)
vehical_car.drive
# Output: Driving a car!
vehicle_truck = VehicleFactory.create(:truck)
vehicle_truck.drive
# Output: Driving a truck!
vehicle_motorcyle = VehicleFactory.create(:motorcycle)
vehicle_motorcyle.drive
# Output: Riding a motorcycle!
Advantages of Factory Method Pattern
- Encapsulation: The factory method encapsulates the instantiation logic, allowing the client code to remain clean and decoupled from concrete classes.
- Flexibility: New vehicle types can be added by extending the factory without modifying the existing code.
- Abstraction: Actual/Client code interacts with the ‘Vehicle’ interface rather than specific classes, which encourages loose coupling.
Conclusion
The Factory Method pattern is an effective technique for handling object generation in a flexible and maintainable manner. Using this technique in Ruby allows us to easily extend the system by adding additional vehicle kinds without changing the fundamental logic, guaranteeing that the code follows SOLID principles.
Cheers :)
Comments powered by Disqus.