千家信息网

Rust中如何实现Builder模式

发表于:2024-09-26 作者:千家信息网编辑
千家信息网最后更新 2024年09月26日,小编给大家分享一下Rust中如何实现Builder模式,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!示例通常在 Rust
千家信息网最后更新 2024年09月26日Rust中如何实现Builder模式

小编给大家分享一下Rust中如何实现Builder模式,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

示例

通常在 Rust 中的实现是通过 不断重建 Builder 来构造最后的类型:

              
struct Counter {    counted1: usize,    counted2: usize,    done: bool,}
struct CounterBuilder { counted1: usize, counted2: usize,}
impl CounterBuilder { // 构建器需要有默认的参数配置,然后从默认配置触发进行构建。 // 不适用 #[derive(std::default::Default)],因为默认配置可能不一样 fn default() -> Self { CounterBuiler { counted1: 5, counted2: 0, } }
// 属性定制方法。消耗原本的构建器,修改属性后重新生成新构建器 fn set_counted1(self, cnt: usize) -> Self { self.counted1 = cnt; self }
fn set_counted2(self, cnt: usize) -> Self { self.counted2 = cnt; self }
// 最后通过 `build` 方法生成所需类型 fn build(self) -> Counter { Counter { counted1: self.counted1, counted2: self.counted2, done: false, } }}

个人实践

在设置属性方法的时候,通常的实现是通过消耗原本的构造器后生成新构造器,这使得如果配置构造器的过程不能连续调用属性设置方法时,必须重新捕获构造器:

              
let mut builder = CounterBuilder::default();
// ... 进行一些计算,获得需要配置的值let cnt1 = operations();
builder = builder.set_counted1(cnt);
// ... 进行一些计算,获得需要配置的值let cnt2 = operations();
builder = builder.set_counted(cnt2);

以上代码通常出现在需要流计算并及时记录参数配置的时候。并且,如果构造器被更大型的数据结构持有时,消耗并重新构建构造器可能会对性能有点影响。因此在博主个人实现时通常采取传递&mut self 引用的方法来实现属性设置方法:

              
    // ...    // 属性定制方法。消耗原本的构建器,修改属性后重新生成新构建器    fn set_counted1(&mut self, cnt: usize) -> &mut Self {        self.counted1 = cnt;        self    }
fn set_counted2(&mut self, cnt: usize) -> &mut Self { self.counted2 = cnt; self }
// ...

改成如上形式的函数签名,即可 灵活构造 目标结构:

              
let mut builder = CounterBuilder::default();
// ... 进行一些计算,获得需要配置的值let cnt1 = operations();
builder.set_counted1(cnt);
// ... 进行一些计算,获得需要配置的值let cnt2 = operations();
builder.set_counted(cnt2);
// ... 可能还要等待别的操作完成后再进行构建
let counter = builder.build();

为什么使用构造器模式

  • 构造过程可控。通常实现构造器模式的时候,我们会将构造器所需要配置的属性设置为私有[^1],并且只能通过我们提供的属性设置方法进行设置,使得构造过程可控。另外,可以通过属性设置方法提前恐慌(panic)来阻止生成无效对象。
  • 设置方法职责专一。属性设置方法 [职责专一],只会负责设置一种属性,只有在该属性的设置规则改变时,相应的属性设置方法才需要进行修改;
  • 构造灵活。多个属性设置方法可以自由的组合在一起,也可以分步组合构造。
  • 可批量构造。我们除了使用消耗性的 build(self) 方法,也可以使用非消耗性的 fn build(&self) 方法,使得构造器可以多次复用。
  • 符合开闭原则。当某一属性的设置方法内部实现发生变化的时候,不影响其他属性的设置方式;而新增属性及其设置方法时,可以通过链式调用很方便地增加新属性的设置。

为什么不使用构造器模式

构造器模式由于有以下缺点而在部分场景中不适用:

  • 在构造完成前无法使用被构造对象。在构造完成之前,构造器并不生成被构造对象,因此在整个构造设置完成之前,无法使用被构造对象。
  • 构造器与被构造对象使用相同的属性设置方法,造成代码重复并无法复用。考虑需要只通过属性设置方法来修改对象的场景,当被构造对象在使用过程中需要频繁设置属性,那么就需要编写对应的属性设置方法;而如果还使用构造器进行对象构造,那么属性设置方法就会重复,并且可能造成构造器与被构造对象的属性设置行为不一致的问题[^2]。


以上是"Rust中如何实现Builder模式"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

属性 方法 构造器 配置 对象 模式 消耗 生成 时候 过程 原本 篇文章 专一 个人 代码 内容 参数 可以通过 场景 消耗性 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 服务器上可以访问不了 护苗网络安全知识平台 昆山数据网络技术哪个好 武邑县网络安全工作培训 阿里巴巴网络安全工程师招聘 中宁县软件开发公司怎么样 中国重要报纸全文数据库意义 未找到指定主机名的服务器 漯河手机app软件开发公司 数据库籍贯的字段名 单位办公网络安全 山西软件开发公司薪资待遇 河北信息化软件开发价格优惠 数据库自增主键优点 关于什么是数据库 惠普服务器哪家专业 河南软件开发定制大概价格 不能往硬盘拷贝数据库 无锡个人软件开发推荐咨询 天津联想服务器 ef 与数据库如何映射 数据库禁止添加重复数据语句 minecraft野猪服务器 关于数据库命名的规则 ibm服务器备份 配置数据库的实体路径找不到 金融科技应用与互联网专业一样吗 服务器为什么自带扎带 广州游灵网络技术公司 长沙一众互联网科技有限公司
0