🏗️
[Rustのデザインパターン学習] Builder [生成]
前提
- リンクページ最下部の
See also
セクションで紹介されているderive_builderクレートを使用
内容
- Builderパターンを使い、{日付、内容}項目を持つ日記オブジェクトを作成
サンプルでは2項目に絞っていますが、Builderパターンを用いることで、
項目が増えてもオブジェクトを扱いやすくなるのではないでしょうか
main.rs
#[macro_use]
extern crate derive_builder;
use chrono::prelude::*;
#[derive(Debug,Builder)]
pub struct Diary {
date:NaiveDate,
content:String,
}
fn main() {
let today_diary = DiaryBuilder::default()
.date(Utc::now().date_naive())
.content("It's sunny today.".to_string())
.build();
println!("{:#?}",today_diary.unwrap());
}
実行結果
Diary {
date: 2023-01-08,
content: "It's sunny today.",
}
Cargo.toml
Cargo.toml
[package]
name = "design_pattern"
version = "0.1.0"
edition = "2021"
[dependencies]
chrono = "0.4.23"
derive_builder = "0.12.0"
学習結果
-
struct Diary
に#[derive(Builder)]
を設定した場合-
struct名:
Diary
+Builder
という命名規則でDiaryBuilder
が自動実装される
-
struct
の要素名で関数が自動実装される
-
今後改善したい箇所
-
date(&mut self, value: NaiveDate)
で今日の日付を設定していますが、default()
で設定しておきたい
Trait std::default::Default -
content(&mut self, value: String)
の引数を&strで渡せるよう実装to_string()
を書かなくていいように
main.rs
use chrono::prelude::*;
#[derive(Debug)]
pub struct Diary {
date:NaiveDate,
content:String,
}
#[derive(Default,Debug)]
pub struct DiaryBuilder {
date:NaiveDate,
content:String,
}
impl DiaryBuilder {
pub fn date(mut self, date: NaiveDate) -> DiaryBuilder {
self.date = date;
self
}
pub fn content(mut self, content: &str) -> DiaryBuilder {
self.content = content.to_string();
self
}
pub fn build(self) -> Diary {
Diary {
date: self.date,
content: self.content,
}
}
}
fn main() {
let today_diary = DiaryBuilder::default()
.date(Utc::now().date_naive())
.content("It's sunny today.")
.build();
println!("{:#?}",today_diary);
}
実行結果
Diary {
date: 2023-01-08,
content: "It's sunny today.",
}
Cargo.toml
Cargo.toml
[package]
name = "design_pattern"
version = "0.1.0"
edition = "2021"
[dependencies]
chrono = "0.4.23"
所感
- ぜひderive_builderクレートを使っていきたいです。
Discussion