• 基于Rust语言实现的策略模式
  • 发布于 1个月前
  • 62 热度
    0 评论
  • 太伤人
  • 1 粉丝 28 篇博客
  •   
策略模式介绍
策略模式是一种行为设计模式,允许你定义一系列算法,将它们封装为一个对象,并借助特征使它们可互换。
1,上下文想要应用某种算法,为此它包含了一个实现algorithm方法的Strategy特征。
2,当需要该策略时,将启动StrategyA或StrategyB,并调用算法方法。

有人认为这是依赖注入的一种形式,因为方法只在接口上调用,而不是在具体对象上调用。

在Rust中实现策略模式
新建一个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类型,它使代码更具可读性。这种模式也可以说是依赖注入的一种形式,因为在调用方不知道底层类的情况下,只调用接口上的方法。
用户评论