From 4318828f21fa8af6a95952b8b583fb9977bacfa5 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 2 Nov 2020 12:08:49 +0100 Subject: [PATCH 1/2] Document doer object anti-pattern --- docs/dev/style.md | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/docs/dev/style.md b/docs/dev/style.md index 7a64a0d228c..720231c2dad 100644 --- a/docs/dev/style.md +++ b/docs/dev/style.md @@ -211,6 +211,60 @@ impl Foo { Prefer `Default` even it has to be implemented manually. +## Functions Over Objects + +Avoid creating "doer" objects. +That is, objects which are created only to execute a single action. + +```rust +// Good +do_thing(arg1, arg2); + +// Not as good +ThingDoer::new(arg1, arg2).do(); +``` + +Note that this concerns only outward API. +When implementing `do_thing`, it might be very useful to create a context object. + +```rust +pub fn do_thing(arg1: Arg1, arg2: Arg2) -> Res { + let mut ctx = Ctx { arg1, arg2 } + ctx.run() +} + +struct Ctx { + arg1: Arg1, arg2: Arg2 +} + +impl Ctx { + fn run(self) -> Res { + ... + } +} +``` + +The difference is that `Ctx` is an impl detail here. + +Sometimes a middle ground is acceptable if this can safe some busywork: + +```rust +ThingDoer::do(arg1, arg2); + +pub struct ThingDoer { + arg1: Arg1, arg2: Arg2, +} + +impl ThingDoer { + pub fn do(arg1: Arg1, arg2: Arg2) -> Res { + ThingDoer { arg1, arg2 }.run() + } + fn run(self) -> Res { + ... + } +} +``` + ## Avoid Monomorphization Rust uses monomorphization to compile generic code, meaning that for each instantiation of a generic functions with concrete types, the function is compiled afresh, *per crate*. From 412d6b3db54a7efccf625d16d1e829cb7b5b1def Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 2 Nov 2020 12:17:34 +0100 Subject: [PATCH 2/2] Update docs/dev/style.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Laurențiu Nicola --- docs/dev/style.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/style.md b/docs/dev/style.md index 720231c2dad..8d57fc04983 100644 --- a/docs/dev/style.md +++ b/docs/dev/style.md @@ -246,7 +246,7 @@ impl Ctx { The difference is that `Ctx` is an impl detail here. -Sometimes a middle ground is acceptable if this can safe some busywork: +Sometimes a middle ground is acceptable if this can save some busywork: ```rust ThingDoer::do(arg1, arg2);