aboutsummaryrefslogtreecommitdiff
path: root/docs/dev
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-11-02 11:08:49 +0000
committerAleksey Kladov <[email protected]>2020-11-02 11:13:59 +0000
commit4318828f21fa8af6a95952b8b583fb9977bacfa5 (patch)
treef57360c8f844820880375eeba1611d2d00a1634f /docs/dev
parente7f90866bcf4b04a11e958eda0ac53f7ff0a607b (diff)
Document doer object anti-pattern
Diffstat (limited to 'docs/dev')
-rw-r--r--docs/dev/style.md54
1 files changed, 54 insertions, 0 deletions
diff --git a/docs/dev/style.md b/docs/dev/style.md
index 7a64a0d22..720231c2d 100644
--- a/docs/dev/style.md
+++ b/docs/dev/style.md
@@ -211,6 +211,60 @@ impl Foo {
211 211
212Prefer `Default` even it has to be implemented manually. 212Prefer `Default` even it has to be implemented manually.
213 213
214## Functions Over Objects
215
216Avoid creating "doer" objects.
217That is, objects which are created only to execute a single action.
218
219```rust
220// Good
221do_thing(arg1, arg2);
222
223// Not as good
224ThingDoer::new(arg1, arg2).do();
225```
226
227Note that this concerns only outward API.
228When implementing `do_thing`, it might be very useful to create a context object.
229
230```rust
231pub fn do_thing(arg1: Arg1, arg2: Arg2) -> Res {
232 let mut ctx = Ctx { arg1, arg2 }
233 ctx.run()
234}
235
236struct Ctx {
237 arg1: Arg1, arg2: Arg2
238}
239
240impl Ctx {
241 fn run(self) -> Res {
242 ...
243 }
244}
245```
246
247The difference is that `Ctx` is an impl detail here.
248
249Sometimes a middle ground is acceptable if this can safe some busywork:
250
251```rust
252ThingDoer::do(arg1, arg2);
253
254pub struct ThingDoer {
255 arg1: Arg1, arg2: Arg2,
256}
257
258impl ThingDoer {
259 pub fn do(arg1: Arg1, arg2: Arg2) -> Res {
260 ThingDoer { arg1, arg2 }.run()
261 }
262 fn run(self) -> Res {
263 ...
264 }
265}
266```
267
214## Avoid Monomorphization 268## Avoid Monomorphization
215 269
216Rust 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*. 270Rust 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*.