Creational Design Patterns: Abstract Factory Method
Purpose
The Abstract Factory pattern is like a blueprint for creating different “families” of objects without telling the program exactly which specific objects to create. Imagine it as a factory that makes a set of related products, like a car factory that makes engines and tires. You can ask the factory for a car, and it will give you the right kind of engine and tires without you needing to know how they’re made.
In short, this pattern helps you:
- Create groups of related objects (like car parts or motorcycle parts).
- Change the specific parts being created without modifying your code everywhere.
- Ensure that the parts are compatible with each other.
Explanation
Let’s say we have two types of vehicles: Cars and Motorcycles. Each vehicle needs two parts: an Engine and Tires. But the car and the motorcycle have different engines and tires (e.g., car engines are more powerful, and motorcycle tires are made for different terrains).
Using the Abstract Factory pattern, we would create two factories:
- Car Factory: This factory knows how to make a car engine and car tires.
- Motorcycle Factory: This factory knows how to make a motorcycle engine and motorcycle tires.
Now, you (as the programmer) don’t need to know all the details about how engines or tires are made. You just ask the right factory for the parts. The factory will give you the correct parts that fit together.
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 Parts(Products)
First, we define the vehicle parts. There are two parts: the Engine and Tires.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Abstract class for Engine
class Engine
def specs
raise NotImplementedError, "This method should be overridden"
end
end
# Abstract class for Tires
class Tires
def specs
raise NotImplementedError, "This method should be overridden"
end
end
Step 2: Create Concrete Parts
Now, we define specific parts for cars and motorcycles.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Car-specific parts
class CarEngine < Engine
def specs
"Car engine: 200 horsepower"
end
end
class CarTires < Tires
def specs
"Car tires: Smooth road tread"
end
end
# Motorcycle-specific parts
class MotorcycleEngine < Engine
def specs
"Motorcycle engine: 100 horsepower"
end
end
class MotorcycleTires < Tires
def specs
"Motorcycle tires: Rough off-road tread"
end
end
Step 3: Create the Factory Method
Next, we create the factories that produce the correct parts.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# Abstract factory class
class VehicleFactory
def create_engine
raise NotImplementedError, "This method should be overridden"
end
def create_tires
raise NotImplementedError, "This method should be overridden"
end
end
# Car Factory
class CarFactory < VehicleFactory
def create_engine
CarEngine.new
end
def create_tires
CarTires.new
end
end
# Motorcycle Factory
class MotorcycleFactory < VehicleFactory
def create_engine
MotorcycleEngine.new
end
def create_tires
MotorcycleTires.new
end
end
Step 4: Using the Factory Method
Finally, we use these factories to create vehicles without knowing the details.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def build_vehicle(factory)
engine = factory.create_engine
tires = factory.create_tires
puts "Engine: #{engine.specs}"
puts "Tires: #{tires.specs}"
end
car_factory = CarFactory.new
puts "Building a car:"
build_vehicle(car_factory)
puts "-------------------"
motorcycle_factory = MotorcycleFactory.new
puts "Building a motorcycle:"
build_vehicle(motorcycle_factory)
Output:
1
2
3
4
5
6
7
Building a car:
Engine: Car engine: 200 horsepower
Tires: Car tires: Smooth road tread
-------------------
Building a motorcycle:
Engine: Motorcycle engine: 100 horsepower
Tires: Motorcycle tires: Rough off-road tread
Conclusion
The Abstract Factory pattern allows you to build families of related objects (like vehicle parts) without worrying about the specifics of how those objects are created. It’s like giving an order to a specialized factory and getting the right parts, whether for a car, motorcycle, or any other vehicle!
Cheers :)
Comments powered by Disqus.