繁体   English   中英

如何实现这个 API? 这是一个接受通用(或特征)参数的 Builder 模式

[英]How do I implement this API? It's a Builder pattern that takes generic (or trait) params

设想

想象你是一个面包师。 您使用不同的食谱烘烤不同的蛋糕。

目标

您正在尝试使用即将到来的订单列表来计划在接下来的 6m 内您需要多少原料。

挑战在于,您的订单不确定。 它们基于概率。

问题

我已经开始了halo - 一个运行此类模拟的库。 我被困在如何实现我想象的 API 的人体工程学上。 这是我的想法:

struct Sugar(f32);
struct Chocolate(f32);
struct Vanilla(f32);

let brownieRecipe = RecipeBuilder::default()
    .add(Sugar(200.0))
    .add(Chocolate(10.0))
    .build();

let vanillaSponge = RecipeBuilder::default()
    .add(Sugar(300.0))
    .add(Vanilla(2.0))
    .build();

let p1 = AllocationBuilder::default()
    .recipe(brownieRecipe)
    .duration_weeks(5)
    .start_date(&(today + Duration::weeks(8)))
    .build();

let p2 = AllocationBuilder::default()
    .recipe(vanillaSponge)
    .duration_weeks(2)
    .start_date(&(today + Duration::weeks(2)))
    .build();

RecipeBuilder从任意数量的成分构建配方。 AllocationBuilder在需要时采用配方和计划。

下一步是为 plot 10k 结果实现模拟引擎(但这不在此问题的 scope 范围内)。

成分结构最终可能会实现一些特征,以便可以对它们求和( std::Add ?)。

你需要有一些使用这些成分的特性。 什么特征-这取决于您需要对它们做什么。 它可以是内置特征或自定义特征,但重要的是所有成分( SugarChocolate等)都将实现它(我将 go 与自定义特征)。

假设您有一个特征Ingredient ,存储Vec<Box<dyn Ingredient>>的列表。 要使 API 成为您所描述的,您需要将add()方法定义为:

pub fn add<I: Ingredient>(&mut self, ingredient: I) {
    self.ingredients.push(Box::new(ingredient));
}

这是一种方便的方法:不需要传递Box<dyn Ingredient> ,而是传递impl Ingredient并且该方法创建Box<dyn Ingredient> 这是 Rust 中非常常见的模式。

结合@chayim-friedman 和@blackbeans 的详细信息,我们得到了它!

pub fn add<I: Ingredient>(&mut self, ingredient: I) -> self {
    self.ingredients.push(Box::new(ingredient));
    self
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM