Design Pattern in Rust: Builder

Design Pattern in Rust: Builder

Ly Nhan

2 years 5 min read

Builder pattern đơn giản hóa việc khởi tạo những object có constructor phức tạp bằng cách tách các params của constructor này thành các method builder.

Ví dụ

Một sql query cần có table name, select.... mình sẽ design function query như này:

fn nextlint_query<'a>(table:&'a str)->{
  db.select("*").from(table)
}

Như vậy khi các table sử dụng sẽ truyền table name vào:

next_query("posts")
next_query("users")
next_query("comments")

Ổn áp nhỉ, nhìn có vẻ như tái sử dụng được nhiều hen :))). Okie giờ giả sử mình muốn thêm limit, offset vào next_query thì sao ???

Sẽ có 2 cách (1) mình sửa lại constructor của function next_query, (2) mình sẽ viết lại function khác.

Nếu mình chọn cách số 1 thì sao: việc sửa lại constructor sẽ khiến những function đang chạy bị quăng lỗi, mình phải đi tìm tất cả những chỗ sử dụng function này để fix, và mình sẽ lặp đi lặp lại việc như này mỗi lần mình sửa constructor. Thêm cái nữa là trong code mình phải if-else rất nhiều để cover hết các params được truyền vào.

Nếu mình chọn cách số 2: thì việc lặp code sẽ nhất nhiều, mình tính sơ sơ nếu constructor có 3 params sẽ có 7 functions bạn cần viết., 4 params ~18 functions. Chưa kể viết nhiều function bạn cũng không quản lý hết nổi.

Nếu là mình phải chọn 1 trong 2 thì chắc là mình sẽ chọn cách 1 rồi :))). Vậy ở đây để giải bài toán 1 để khởi tạo 1 query builder Object, constructor nhận vào duy nhất một params table, còn lại những params khác như limit, offset, select mình sẽ để None và cung cấp một method để update các thuộc tính trên.

nextlint

Implement method để update các thuộc tính trên:

nextlint

Cuối cùng mình sẽ implement builder function:

nextlint

Usage:

nextlint

Diagram ở dưới đây sẽ một phần nào cho các bạn hình dung được workflow của pattern này.

nextlint

Với builder pattern, constructor hầu như sẽ không bị thay đổi theo thời gian, khi mình thêm một field mới vào query builder, mình chỉ cần làm 2 việc:

1. Implement method update field mới.

2. Implement builder method để khởi tạo query dựa vào field này.

Tất cả những chỗ nào sử dụng QueryBuilder vẫn work bình thường.

Tính ứng dụng:

  • Thuật toán khởi tạo một object phức tạp phải độc lập với các thành phần cấu tạo nên object.

  • Từ một constructor có thể khởi tạo nhiều object có các thuộc tính khác nhau.

Source

https://github.com/lynhan318/rust-design-pattern/blob/main/crates/creational/src/builder.rs

High level experience in web design and development knowledge, producing quality work.

© Nextlint_2023 All Rights Reserved

Privacy Policy Terms of Use