策略模式是一种行为设计模式,允许你定义一系列算法,将它们封装为一个对象,并借助特征使它们可互换。
有人认为这是依赖注入的一种形式,因为方法只在接口上调用,而不是在具体对象上调用。
新建一个Rust项目:
cargo new strategy_pattern
我们将从定义TravelStrategy开始
trait TravelStrategy {
fn travel(&self, distance: i16);
}
然后我们将定义TrainStrategy:
struct TrainStrategy;
impl TravelStrategy for TrainStrategy {
fn travel(&self, distance: i16) {
println!("Travelled {} km by train", distance);
}
}
TrainStrategy结构体为空。我们在上面实现了一个travel方法,它只是打印旅行的距离。
CarStrategy也类似:
struct CarStrategy;
impl TravelStrategy for CarStrategy {
fn travel(&self, distance: i16) {
println!("Travelled {} km by car", distance);
}
}
定义TravelHub
struct TravelHub<T: TravelStrategy> {
strategy: T,
}
我们在这里使用泛型,T: TravelStrategy意味着我们可以拥有任何类型,只要它实现了TravelStrategy特征。
为什么是泛型?泛型使得在具体类中传递更容易,而无需求助于Box或类似的方法,并且它使代码更具可读性。
现在实现TravelHub:
impl<T: TravelStrategy> TravelHub<T> {
fn new(strategy: T)->Self {
Self {
strategy
}
}
fn customer_travel(&self, distance:i16) {
self.strategy.travel(distance);
}
}
1,首先定义一个构造函数,它获取一个具体类作为形参。这个具体的类必须实现TravelStrategy特性。
2,然后我们定义customer_travel方法,它只调用所选策略上的travel方法。
测试
fn main() {
let travelhub = TravelHub::new(TrainStrategy{});
travelhub.customer_travel(20);
}
用TrainStrategy作为参数实例化一个travelhub。由于TrainStrategy实现了TravelStrategy特性,我们可以将其作为参数传递。
执行cargo run,结果如下:
Travelled 20 km by train
如你所见,实现非常简单。泛型的使用可以避免使用Box类型,它使代码更具可读性。这种模式也可以说是依赖注入的一种形式,因为在调用方不知道底层类的情况下,只调用接口上的方法。
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8