构建器模式是一种创建设计模式,也就是说,它是一种用于创建或实例化类对象的模式。它用于将构建过程分解为更小、更易于管理和可测试的步骤。
在Rust中,我们可以使用结构体和特征来实现这个模式。
如图:
1,Director:这是构建器的客户端,它请求构建一些产品。
2,Builder:这是任何生成器的通用接口,它包含构建Product的方法。
3,ConcreteBuilder:这是构建Product的具体类。因为我们只能使用一个接口,所以可以交换不同的ConcreteBuilders实例来构建不同的产品。
4,我们要构建的产品是Product,这也可以定义一个接口。
新建一个Rust项目:
cargo new rust_builder
Bicycle结构体
#[derive(Clone,Debug)]
pub struct Bicycle {
number_of_wheels: i8,
bike_type: String
}
impl Bicycle {
fn new()->Self {
Bicycle { number_of_wheels: 0, bike_type: "".to_string() }
}
}
1,Bicycle结构体只有两个字段:number_of_wheels和bike_type。
2,我们用空值为Bicycle定义了一个构造函数。
3,Bicycle结构体有两个特征:- Clone,因此我们可以从构建器返回一个克隆;
pub trait BicycleBuilder {
fn add_wheels(&mut self)->&mut dyn BicycleBuilder;
fn set_type(&mut self)->&mut dyn BicycleBuilder;
fn build(&self) -> Bicycle;
}
1,trait有三个方法:add_wheels用来设置轮子的数量,set_type用来设置自行车类型,还有一个build方法用来返回Bicyle。
2,add_wheels和set_type接受一个可变的self作为参数,因为它们改变了bicycle字段。
3,因为build只返回一个克隆,不需要也不希望有可变性。
4,add_wheels和set_type方法返回指向dyn BicycleBuilder的指针。这是因为BicycleBuilder是一个特征,我们需要动态调度。
struct ATBBuilder {
bicycle: Bicycle
}
impl BicycleBuilder for ATBBuilder {
fn add_wheels(&mut self) -> &mut dyn BicycleBuilder {
self.bicycle.number_of_wheels=2;
self
}
fn set_type(&mut self) -> &mut dyn BicycleBuilder {
self.bicycle.bike_type="ATB".to_string();
self
}
fn build(&self)->Bicycle {
self.bicycle.clone()
}
}
1,ATBBuilder包含要生产的产品,即自行车。
2,实现非常简单,所有的方法都返回self,所以它们可以被链式调用。
3,build方法返回一个克隆。
为了更好地衡量,我们还可以引入一个StreetBikeBuilder:
struct StreetBikeBuilder {
bicycle:Bicycle
}
impl BicycleBuilder for StreetBikeBuilder {
fn add_wheels(&mut self) -> &mut dyn BicycleBuilder {
self.bicycle.number_of_wheels=3;
self
}
fn set_type(&mut self) -> &mut dyn BicycleBuilder {
self.bicycle.bike_type="Street".to_string();
self
}
fn build(&self)->Bicycle {
self.bicycle.clone()
}
}
使用BikeEngineer组合
struct BikeEngineer {
builder: Box<dyn BicycleBuilder>
}
impl BikeEngineer {
fn new(builder: Box<dyn BicycleBuilder>)->Self {
BikeEngineer { builder: builder }
}
fn construct_bike(&mut self)->Bicycle {
self.builder
.add_wheels()
.set_type()
.build()
}
}
1,我们有Box
2,我们定义了一个接受这样一个box的构造函数,并将其分配给生成器字段。还要注意,我们返回Self。
3,construct_bike方法只是添加轮子,设置类型并返回成品。
fn main() {
let builder=Box::new(StreetBikeBuilder{bicycle:Bicycle::new()});
let mut engineer=BikeEngineer::new(builder);
let bike=engineer.construct_bike();
println!("{:?}",bike);
}
执行cargo run,结果如下:
Bicycle { number_of_wheels: 3, bike_type: "Street" }
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8