在这篇简短的文章中,我描述并命名了构建器模式的表亲——builder lite。
与使用单独的构建器对象的传统构建器不同,构建器精简版重用对象本身来提供构建器功能。
这是一个builder lite说明性示例
pub struct Shape { position: Vec3, geometry: Geometry, material: Option<Material>, }
impl Shape { pub fn new(geometry: Geometry) -> Shape { Shape { position: Vec3::default(), geometry, material: None, } }
pub fn with_position(mut self, position: Vec3) -> Shape { self.position = position; self }
pub fn with_material(mut self, material: Material) -> Shape { self.material = Some(material); self } }
// Call site
let shape = Shape::new(Geometry::Sphere::with_radius(1)) .with_position(Vec3(0, 9, 2)) .with_material(Material::SolidColor(Color::Red));
|
builder-lite 的主要好处是它是new方法的增量、零成本演进。因此,它在代码快速发展、方向不确定的情况下特别有用。也就是说,在构建应用程序而不是库时适用。
相比之下,完全的构建器builder在定义站点要冗长得多,并且需要在调用站点进行一些额外的调用,如下:
pub struct Shape { position: Vec3, geometry: Geometry, material: Option<Material>, }
pub struct ShapeBuilder { position: Option<Vec3>, geometry: Option<Geometry>, texture: Option<Texture>, }
impl Shape { pub fn builder() -> ShapeBuilder { ... } }
impl ShapeBuilder { pub fn position(&mut self, position: Vec3) -> &mut Self { ... } pub fn geometry(&mut self, geometry: Geometry) -> &mut Self { ... } pub fn material(&mut self, material: Material) -> &mut Self { ... } pub fn build(&self) -> Shape { ... } }
// Call site
let shape = Shape::builder() .position(Vec3(9, 2)) .geometry(Geometry::Sphere::with_radius(1)) .material(Material::SolidColor(Color::Red)) .build();
|