I want to study design pattern use rust language. From this code it works properly but it uses dynamic dispatch. How can I change the code to use static dispatch? Thanks!
trait Shape {
fn draw(&self);
}
enum ShapeType {
Rectangle,
Circle,
}
struct Rectangle {}
impl Shape for Rectangle {
fn draw(&self) {
println!("draw a rectangle!");
}
}
struct Circle {}
impl Shape for Circle {
fn draw(&self) {
println!("draw a circle!");
}
}
struct ShapeFactory;
impl ShapeFactory {
fn new_shape(s: &ShapeType) -> Box<dyn Shape> {
match s {
ShapeType::Circle => Box::new(Circle {}),
ShapeType::Rectangle => Box::new(Rectangle {}),
}
}
}
fn main() {
let shape = ShapeFactory::new_shape(&ShapeType::Circle);
shape.draw(); // output: draw a circle!
let shape = ShapeFactory::new_shape(&ShapeType::Rectangle);
shape.draw(); // output: draw a rectangle!
}
In the provided example, I would add
enum StaticShape {
Rectangle(Rectangle),
Circle(Circle),
}
impl Shape for StaticShape {
fn draw(&self) {
match self {
StaticShape::Rectangle(sh) => sh.draw(),
StaticShape::Circle(sh) => sh.draw(),
}
}
}
struct StaticShapeFactory;
impl StaticShapeFactory {
fn new_shape(s: &ShapeType) -> StaticShape {
match s {
ShapeType::Rectangle => StaticShape::Rectangle(Rectangle {}),
ShapeType::Circle => StaticShape::Circle(Circle {}),
}
}
}
and in the main()
function
let shape = StaticShapeFactory::new_shape(&ShapeType::Circle);
shape.draw(); // output: draw a circle!
let shape = StaticShapeFactory::new_shape(&ShapeType::Rectangle);
shape.draw(); // output: draw a rectangle!
The StaticShape
enum enumerates every possible specific shape that can be handled.
In order to behave as a shape, it implements the Shape
trait by simply forwarding the call to the specific shape types.
The corresponding factory is very similar to the dynamic one; it just builds the specific variant of the returned enum instead of a box.