Browse Source

New chapter: magical number seven

master
Julio Biason 5 years ago
parent
commit
24b06878f6
  1. 1
      content/books/things-i-learnt/_index.md
  2. 2
      content/books/things-i-learnt/data-flow/index.md
  3. 2
      content/books/things-i-learnt/integration-tests/index.md
  4. 86
      content/books/things-i-learnt/magical-number-seven/index.md

1
content/books/things-i-learnt/_index.md

@ -14,6 +14,7 @@ template = "section-contentless.html"
* [Gherkin Is Your Friend to Understand Expectations](gherkin)
* [Design Patters Are Used to Name Solution, Not Find Them](patterns-not-solutions)
* [Thinking Data Flow Beats Patterns](data-flow)
* [The Magic Number Seven, Plus Or Minus Two](magical-number-seven)
* Testing Software
* [Unit Tests Are Good, Integration Tests Are Gooder](integration-tests)
* [Testing Every Function Creates Dead Code](tests-dead-code)

2
content/books/things-i-learnt/data-flow/index.md

@ -32,4 +32,4 @@ In a way, this way of thinking gets things more clear 'cause you have a list
of steps of transformations you need to do, so you can write them one after
another, which prevents a lot of bad code in the future.
{{ chapters(prev_chapter_link="/books/things-i-learnt/patterns-not-solutions", prev_chapter_title="Design Patters Are Used to Name Solution, Not Find Them", next_chapter_link="/books/things-i-learnt/integration-tests", next_chapter_title="Unit Tests Are Good, Integration Tests Are Gooder") }}
{{ chapters(prev_chapter_link="/books/things-i-learnt/patterns-not-solutions", prev_chapter_title="Design Patters Are Used to Name Solution, Not Find Them", next_chapter_link="/books/things-i-learnt/magical-number-seven", next_chapter_title="The Magic Number Seven, Plus Or Minus Two") }}

2
content/books/things-i-learnt/integration-tests/index.md

@ -66,4 +66,4 @@ parts.
[^1]: There is no "unit" in "unit tests". "Unit test" means the test _is_ a
unit, indivisible and dependent only on itself.
{{ chapters(prev_chapter_link="/books/things-i-learnt/data-flow", prev_chapter_title="Thinking Data Flow Beats Patterns", next_chapter_title="Testing Every Function Creates Dead Code", next_chapter_link="/books/things-i-learnt/tests-dead-code") }}
{{ chapters(prev_chapter_link="/books/things-i-learnt/magical-number-seven", prev_chapter_title="The Magic Number Seven, Plus Or Minus Two", next_chapter_title="Testing Every Function Creates Dead Code", next_chapter_link="/books/things-i-learnt/tests-dead-code") }}

86
content/books/things-i-learnt/magical-number-seven/index.md

@ -0,0 +1,86 @@
+++
title = "Things I Learnt The Hard Way - The Magical Number Seven, Plus Or Minus Two"
date = 2019-06-26
[taxonomies]
tags = ["en-au", "books", "things i learnt", "complexity"]
+++
"[The magical number](https://en.wikipedia.org/wiki/The_Magical_Number_Seven,_Plus_or_Minus_Two)"
is a psychology article about the number of things one can keep in their mind
at the same time.
<!-- more -->
I've seen twice this weird construction on where a function would do some
processing, but its return value was the return of a second function and
some bit of processing. Nothing major. But the second function would also do
some processing and call a third function. And the third function would call a
fourth. And the fourth a fifth. And the fifth, a sixth function.
Something like this
```
func_1
+-- func_2
+-- func_3
+-- func_4
+-- func_5
+-- func6
```
Now, when you're trying to understand this kind of code to find a problem,
you'll have to keep in mind what the first, second, third, fourth, fifth and
sixth functions do, 'cause they are all calling each other (inside them).
This causes some serious mental overflow that shouldn't be necessary.
Not only that, but imagine that you put a log before and after `func_1`: The
log before points the data that's being send to func_1, and the log after its
result.
So you'd end up with the impression that `func_1` does a lot of stuff, when it
actually is passing the transformation along.
(I got a weird experience with a function called `expand`, which logging
before the call would show some raw, compressed data, but the after was not
the expanded data, but actually a list of already processed data from the
compressed data.)
What would be a better solution, you may ask?
Well, if instead of making `func_1` call `func_2`, you can make it return the
result (which may not be the final result, anyway) and _then_ call `func_2`
with that result.
Something like:
```
result1 = func_1
result2 = func_2(result1)
result3 = func_3(result2)
result4 = func_4(result3)
result5 = func_5(result4)
result6 = func_6(result5)
result7 = func_7(result6)
```
Now you can see _exactly_ how the data is being transfomed -- and, obviously,
the functions would have better names, like `expand`, `break_lines`,
`name_fields` and so on, so you can see that that compressed data I mentioned
before is actually being decompressed, the content is being broke line by
line, the lines are getting names in its fields and so on (and one could even
claim that it would make things clear if there was a function after
`break_lines` which would just `break_fields`, which would make `name_fields`
more obvious -- and in a construction like this it would be almost trivial to
add this additional step).
"But that isn't performant!" someone may cry. Well, maybe it's just a bit less
performant than the original chained-calls ('cause it wouldn't create and
destroy frames in the stack, it would just pile them up and then unstack them
all in the end), but heck, optimization is for compilers, not people. Your job
is to make the code _readable_ and _understandable_. If you need performance,
you can think of a better sequence of steps, not some "let's make this a mess
to read" solution.
{{ chapters(prev_chapter_link="/books/things-i-learnt/data-flow", prev_chapter_title="The Magic Number Seven, Plus Or Minus Two", next_chapter_link="/books/things-i-learnt/integration-tests", next_chapter_title="Unit Tests Are Good, Integration Tests Are Gooder") }}
Loading…
Cancel
Save