Builder pattern

pull/3/head
Nick Cameron 9 years ago
parent 248baabc14
commit ab19516a4f

@ -11,16 +11,46 @@ language.
### Idioms
* [Constructor](idioms/ctor.md)
* [Concatenating strings with `format!`](idioms/concat-format.md)
* private field to indicate extensibility
* trait to separate visibility of methods from visibility of data (https://github.com/sfackler/rust-postgres/blob/master/src/lib.rs#L1400)
* Deref on Vec/String to treat like a smart pointer/borrowed view of such data
* leak amplification ("Vec::drain sets the Vec's len to 0 prematurely so that mem::forgetting Drain "only" mem::forgets more stuff. instead of exposing uninitialized memory or having to update the len on every iteration")
* dtor for finally
* interior mutability - UnsafeCell, Cell, RefCell
* treating Option like a list
### Design patterns
* Builder
* RAII
* [Builder](patterns/builder.md)
* RAII ( + borrows - mutex guard)
* newtype (can be used to restrict functionality, make by-move rather than by-copy, abstraction, e.g., https://github.com/rust-lang/rust/blob/master/src/libcore/str/mod.rs#L366-L372)
* iterators (to safely avoid bounds checks)
* closures and lifetimes (coupling to lifetime)
* platform-specific sub-modules (https://github.com/rust-lang/rfcs/blob/master/text/0517-io-os-reform.md#platform-specific-opt-in)
* affine types/session types
* Entry API vs insert_or_update etc.
* visitor
* fold
* small crates and semver
* extension traits
* destructor bombs (ensure linear typing dynamically, e.g., https://github.com/Munksgaard/session-types/commit/0f25ccb7c3bc9f65fa8eaf538233e8fe344a189a)
* convertible to Foo trait for more generic generics (e.g., http://static.rust-lang.org/doc/master/std/fs/struct.File.html#method.open)
* late binding of bounds for better APIs (i.e., Mutex's don't require Send)
* 'shadow' borrowed version of struct - e.g., double buffering, Niko's parser generator
* composition of structs to please the borrow checker
### Anti-patterns
* thread + catch_panic for exceptions
* Clone to satisfy the borrow checker
* Deref polymorphism
* Matching all fields of a struct (back compat)
* wildcard matches
* tkaing an enum rather than having multiple functions
## Contributing

@ -0,0 +1,88 @@
# Builder
## Description
Construct an object with calls to a builder helper.
## Example
```
struct Foo {
// Lots of complicated fields.
}
struct FooBuilder {
// Probably lots of optional fields.
...
}
impl FooBuilder {
fn new(...) -> FooBuilder {
// Set the minimally required fields of Foo.
}
fn named(mut self, name: &str) -> FooBuilder {
// Set the name on self and return it
}
// More methods that take `mut self` and return `FooBuilder` setting up
// various aspects of a Foo.
...
// If we can get away with not consuming the Builder here, that is an
// advantage. It means we can use the builder as a template for constructing
// many Foos.
fn finish(&self) -> Foo {
// Create a Foo from the FooBuilder.
}
}
fn main() {
let f = FooBuilder::new().named("Bar").with_attirbute(...).finish();
}
```
## Motivation
Useful when you would otherwise require many different constructors or where
construction has side effects.
## Advantages
Separates methods for building from other methods.
Prevents proliferation of constructors
Can be used for one-liner initialisation as well as more complex construction.
## Disadvantages
More complex than creating a struct object directly, or a simple constructor
function.
## Discussion
This pattern is seen more frequently in Rust (and for simpler objects) than in
many other languages because Rust lacks overloading. Since you can only have a
single method with a given name, having multiple constructors is less nice in
Rust than in C++, Java, or others.
This pattern is often used where the builder object is useful in its own right,
rather than being just a builder. For example, see `std::process::Command` is a
builder for `Child` (a process). In these cases, the `T` and `TBuilder` pattern
of naming is not used.
## See also
[Description in the guide](https://aturon.github.io/ownership/builders.html)
[Constructor pattern](../idioms/ctor.md) for when construction is simpler.
[Builder pattern (wikipedia)](https://en.wikipedia.org/wiki/Builder_pattern)
Loading…
Cancel
Save