策略将一组动作行为转化为对象(动词变名词),并使它们在原始上下文对象中可互换。
Rust实现
创建一个表示公共接口的trait并多次实现该trait:
trait Strategy { |
然后实现持有一个实现该trait的泛型类型,Context上下文是一个持有trait实现的数据结构:
struct Context<S> { |
- Rust中泛型:不是像i32或String之类的具体类型。我们可以表达泛型的行为或它们与其他泛型的关系,而不知道编译和运行代码时它们的位置。
泛型可以为编译器提供有关引用如何相互关联的信息 - 生命周期允许我们向编译器提供有关借用值的足够信息,以便它可以确保引用在更多情况下有效
- 可以将接口trait特征与泛型类型结合起来,将泛型类型限制为仅接受具有特定行为的类型,而不是仅接受任何类型。
调用代码:
fn main() { |
第二个Rust案例
函数和闭包简化了策略实现,因为您可以将行为直接注入对象而无需复杂的接口定义。
type RouteStrategy = fn(from: &str, to: &str); |
似乎 Strategy 经常被隐含地广泛使用在 Rust 的现代开发中,例如它就像迭代器一样工作:
let a = [0i32, 1, 2]; |
策略模式也是过滤器的一种实现,不过这种过滤器是一种策略过滤器,非常类似decorator模式,只是不依赖附加于一个固定对象,不同于职责链模式,每个策略过滤器只能有一个策略有效,如果多个策略依次有效,就是策略模式+责任链模式了。
策略模式不同于命令模式,命令模式中任何一个命令的发生都是事先无法控制预测的,而策略模式中策略激活都是事先谋划计划好的,如同诸葛亮的锦囊妙计,需要在特定上下文打开激活,这些策略都是事先计划好放入袋子中,当然料事如神诸葛亮可以这么干,一般人计划能力没有这么强,而且会产生认知心理焦虑,控制力太强并不有益于身心健康。
事先计划设计是一件很繁重的活动,见DDD战略设计 事件风暴 头脑会议。
如果想根据上下文动态执行对应策略,可以通过规则引擎 实现。