#Builder Pattern vs Optional Struct

3 messages · Page 1 of 1 (latest)

neon dagger
#

A question recently came up at work that I don't have a strong answer to: when should one use the builder pattern vs some sort of options struct?

For example, what is the big difference between these two, and when should one be preferred over the other?

struct Foo {
  r1: u32,
  r2: u32,
  o1: Option<u32>,
  o2: Option<u32>,
}

// OPTION 1:

struct FooBuilder {
  r1: u32,
  r2: u32,
  o1: Option<u32>,
  o2: Option<u32>,
}

impl FooBuilder {
  fn new(r1: u32, r2: u32) -> Self;
  fn with_o1(self) -> Self;
  fn with_o2(self) -> Self;
  fn build(&self) -> Foo;
}

// OPTION 2:

// this could have some similar methods to the builder if desired
struct FooOptions {
  o1: Option<32>,
  o2: Option<32>,
}

impl Foo {
  fn new(r1: u32, r2: u32, options: FoOptions) -> Self;
}
frigid holly
#

there is a api guideline related to this https://rust-lang.github.io/api-guidelines/type-safety.html?highlight=builder#builders-enable-construction-of-complex-values-c-builder

Prefer a builder when: building has side effects, you want the public API to be expandable/changeable, the value should be built over multiple phases.

Otherwise a option struct is a good choice do to the minimum extra code needed

#

oh and there is the type state builders which are kind of separate from this as a option struct can't encode what they do