I was looking at the Method syntax section of the Rust documentation and came across an example of the builder pattern. The CircleBuilder
struct in the example below is an exact duplicate of the Circle
struct. It seems like this redundant code violates the usual norms of programming.
I understand why the example created a new struct, because the creator did not want to implement the builder methods against the original Circle
struct. That is fine, but is there a way to rewrite this example so that there is no redundancy--yet still keeping the nice builder interface in the main()
function intact?
I tried to create an empty struct or a struct with just one throwaway element, but that did not work.
struct Circle {
x: f64,
y: f64,
radius: f64,
}
impl Circle {
fn area(&self) -> f64 {
std::f64::consts::PI * (self.radius * self.radius)
}
}
struct CircleBuilder {
x: f64,
y: f64,
radius: f64,
}
impl CircleBuilder {
fn new() -> CircleBuilder {
CircleBuilder { x: 0.0, y: 0.0, radius: 1.0, }
}
fn x(&mut self, coordinate: f64) -> &mut CircleBuilder {
self.x = coordinate;
self
}
fn y(&mut self, coordinate: f64) -> &mut CircleBuilder {
self.y = coordinate;
self
}
fn radius(&mut self, radius: f64) -> &mut CircleBuilder {
self.radius = radius;
self
}
fn finalize(&self) -> Circle {
Circle { x: self.x, y: self.y, radius: self.radius }
}
}
fn main() {
let c = CircleBuilder::new()
.x(1.0)
.y(2.0)
.radius(2.0)
.finalize();
println!("area: {}", c.area());
println!("x: {}", c.x);
println!("y: {}", c.y);
}
Circle
example is a less than ideal choice to demonstrate the builder pattern. Realistic builders often contain entirely different fields than the type they are building. For example,OpenOptions
uses a sophisticated builder to buildFile
which ends up holding a single integer. The same withCommand
, where the resultingChild
ends up holding three file handles and a process handles, again very different than the arguments passed to the builder. A builder that just repeats the type it's building looks like somewhat of an anti-pattern. – user4815162342Command
, don't have that kind of duplication at all and are great examples of the pattern. But the book is developed openly, so instead of typing here I can try to think of a better example and submit a PR. :) – user4815162342