In this lesson, you will learn how to use the Factory Pattern to generate specific object implementations at runtime based on configuration data.
The Problem of Static Initialization
Often, your application needs to create different types of objects based on a user’s input or a configuration file. If you hardcode let item = MyType::new(), your code becomes rigid and difficult to extend. In Rust, because we care about memory safety and type integrity, we use Trait-based Factories to bridge the gap between runtime decisions and compile-time types.
Implementing the Factory Pattern
The core idea is to define a common trait that all your potential objects share. Then, you create a "Factory" function that returns a Box<dyn Trait>, allowing you to return different concrete types from the same function signature.
trait Shape {
fn draw(&self);
}
struct Circle;
impl Shape for Circle { fn draw(&self) { println!("Drawing a circle"); } }
struct Square;
impl Shape for Square { fn draw(&self) { println!("Drawing a square"); } }
fn shape_factory(config: &str) -> Box<dyn Shape> {
match config {
"round" => Box::new(Circle),
_ => Box::new(Square),
}
}
Why This Works
By returning Box<dyn Shape>, you are utilizing Compositional Design (Lesson 6) to hide the specific concrete type from the caller. The caller doesn't need to know if they have a Circle or a Square; they only need to know that the returned object satisfies the Shape trait.
This approach decouples your construction logic from your business logic. If you need to add a new Triangle type later, you simply update the factory. Your main application code, which interacts with the Shape trait, remains completely unchanged. This keeps your system architecture modular and adheres to the open-closed principle, where your code is open for extension but closed for modification.
Key Takeaway: Use trait-based factories to encapsulate instantiation logic, allowing your application to decide which specific type to create at runtime without exposing implementation details to the rest of your system.