The magic combo: label what your code does and break it down to small pieces
Tags: cleancode, javascript, css
Published: 2022-03-31 19:14:36

I start with a statement without scientific data backing me, so this will be the _least mathematical_, _most subjective_ and probably one of the _most useful_ **clean coding** idea:

> Most of us understand short, concise and aptly named and labelled code.

If you think about this, you will see that much of **Clean Coding** is achieving this very idea:
- you want things to be **short**, so you do not need to juggle a lot of context and details at the same time; you toy with _abstractions_ until you can achieve the most effectives ones
- you want things to be **concise and aptly named**, so you can trust that a `getUrl` function does not _in fact_ sets up a server if it is not yet running (this oddly specific example is from real life code, so don't argue with me that _"Who would do such thing?"_)

That's why we are **grouping** and **categorizing** and **recategorizing stuff**, that's why you are breaking up that messy folder that has 20 files to smaller ones.

Because you want to **lower the cognitive load on your brain**, therefore you will be able to do **quicker and smarter decisions**.

> With well isolated modules/functions/components/abstractions you can be quite sure what the consequences of your changes will be.

The opposite is when _everything is_ or _can be_ connected with everything else. That's when you read code for two days to write 3 lines of code.

> To best achieve this isolation you are grouping non-obvious and coherent parts of your code into a named `function`/`method`/`procedure` or `module` with the **name** _explaining_ the otherwise obscure inner workings.

### The tyranny of templates and tutorials (TTT)
While these two technique (naming and breaking down long passages of code) are very basic and taught very early in **clean coding**, there are certain conditions when I saw otherwise excellent developers abandoning these two excellent tools. 

You see, most of us start writing code based on a template (for instance `create-react-app`) or from an existing tutorial. These have to be fairly simple to so people get why things are there and cannot get all encompassing.

But then an aversion to **breaking the template** kicks in and people start writing 1000s of lines of controllers in `app.js` (in case of `express.js`) since this was where the template/tutorial instructed them to put their code into.

This is also true for many popular coding strategies like **test driven development**, **functional programming** or **object oriented programming**: you have a problem that does not fit your favourite paradigm and then you force it upon it, regardless how unreadable your code became.

And that is exactly where you can apply these two techniques to force yourself out from the template to a working new categorization.

> When reality breaks the template, _break the template_ not the very valid use case at hand.

Templates and paradigms are starting points and not unbreakable contracts or standards.

## Examples to open your mind

### Using `@mixin` of `SCSS` to explain `CSS`
For most developers (myself included) `CSS` is scary partly because that not all declarations "do" something unless a _bunch of other declarations were **also** made_. These tend to be _not intuitive_ for a lot of cases.

There is a very quiet revolutionary feature in `SCSS` (or in `LESS`) and that is named `@mixin`s. This would allow us to **name the obscure** and **break it down to small chunks**.

In this little snippet a couple of statements make sure that the `language-input-label` will be the same `width` as the `input` below it.

```sass
.language-input-label {
  // neatly sorted alphabetically 😊
  flex-grow: 1;
  font-size: var(--small-space-1);
  padding: var(--spacing-base);
  text-transform: uppercase;
  width: 100%;
}
```

Can you spot those? Or could you even guess such feature would exist?

See this example instead:
```sass
.language-input-label {
  @mixin make-label-equal-width-as-inputs {
    width: 100%;
    flex-grow: 1;
    padding: var(--spacing-base);
  }

  @include make-label-equal-width-as-inputs;

  text-transform: uppercase;
  font-size: var(--small-space-1);
}
```

See how `@mixin` is shining, not as a tool to reuse code but to explain:

1. your **goal** with the properties (make **label** of **inputs** equal width as the **inputs**)
2. the **number of properties that need to work together** to achieve the desired effect

So when **dev B** comes over to refine the component they would understand what needs to change in concerted effort. Neat!

### Chaining anonymous functions (e.g. array-iteration or RXjs)
There are certain iteration functions (`.map()`, `.filter()`, `.reduce()`, ...) that we learnt to use with **anonymous functions**. When those anonymous functions get obscure there is a tendency to leave them _as-is_ and say _"well, yes, programming can be hard, functional programming is not for everybody"_. 🤷🏼

⚠️ You do not need to understand every line here, don't waste your time if something looks magical. It is obscure for the sake of example. ⚠️

```javascript
// Pseudo code
chatStream
.filter((chat) => {
   if (chat.user[0].name !== 'sender') {
     return true;
   } else {
     return false;
   }
})
.map((chat) => {
  const copiedChat = { ...chat };

  // that neat snippet lifted from stackoverflow
  let d1 = new Date(new Date().getFullYear(), 3, 0);
  d1.setDate(d1.getDate() - d1.getDay());

  let d2 = new Date(new Date().getFullYear(), 10, 0);
  d2.setDate(d2.getDate() - d2.getDay());
  
  if (chat.timestamp > d1 && chat.timestamp < d2) {
     copiedChat.timestamp = new Date();
     copiedChat.timestamp.setHours(d.getHours() - 1);
  }

  // very self-explanatory! 😐
  return copiedChat;
})
.reduce((chat) => {/* other things */})
```

Raise your hand if you would be eager to touch any of this code!

Now let's do the _unimaginable abomination_ and name those anonymous functions (please observe that by defining them outside of the scope those can be exported, reused and/or tested separately!).

```javascript
function filterSenders(chat: Chat) {
   return chat.user[0].name !== 'sender';
}

// now that everyone knows what this is all about
// maybe you can search or a standard solution...
function correctTimeWith1HourDuringSummerTime(chat: Chat) {
 const copiedChat = { ...chat };

  let d1 = new Date(new Date().getFullYear(), 3, 0);
  d1.setDate(d1.getDate() - d1.getDay());

  let d2 = new Date(new Date().getFullYear(), 10, 0);
  d2.setDate(d2.getDate() - d2.getDay());
  
  if (chat.timestamp > d1 && chat.timestamp < d2) {
     copiedChat.timestamp = new Date();
     copiedChat.timestamp.setHours(d.getHours() - 1);
  }

  return copiedChat;
}

// Look how concise and readable it became! ✅
chatStream
.filter(filterSenders)
.map(correctTimeWith1HourDuringSummerTime)
.reduce(createSomeObject)
```

### `describe` how `it` is the only way in testing
I do not wish to article to be too long, so I will be using quite general terms here.

Another pattern I saw where people merrily copy-paste gigantic amount of code and let a file grow larger than 500+ lines is testing.

The template for testing in `jest` for instance looks like this:
```javascript
// imports

describe('The block under test', () => {
  let mock1;
  let mock2;
  let object1;
  let object2;
  // ...

  beforeEach(() => {
    // setup
  });
  
  afterEach(() => {
    // tear down
  });
  
  it('does things', () => {});
  it('does other things', () => {});
  it('does even more other things', () => {});
  // ...
});
```

When it gets too large why not _a) break it down_ to smaller chunks and _b) name them_ well.

```
// you can import test helper functions 
// you made for your cases!

describe('The block under test', () => {
  let mock1;
  let mock2;
  let object1;
  let object2;
  // ...

  beforeEach(() => {
    // why not name these setup steps?
    setupCommonMocks();
    setupCommonObjects();
  });
  
  it('does things', () => {});
  it('does other things', () => {});
  it('does even more other things', () => {});
  // ...

  function setupCommonMocks() {
     mock1 = jest.spyOn('something');
     mock2 = jest.fn();
     // ...
  }

  // Why copy-paste the creation of that 
  // same complicated initial state?
  function createComplicatedInitialState({ flagToDoSomethingDifferently }) {
     return {
        state1,
        state2,
        state3: flagToDoSomethingDifferently ? object1 : object2
     }
  }
});

```

## The takeaway
What I wished to express that _templates_ and _tutorials_ are just scaffolding to start your code with. Remember:

> Templates + the way of the tutorial < your good sense to write short, well named code.

Happy cleaning up! 🙂