リーダブルコードを咀嚼する(第一章)

## 経緯
現場で誰もが理解しやすいコード、改修しやすいコードを書くことができなかったことで、思わぬバグを生み出す結果になってしまったため。

## 目的
新規参画者でもすぐに理解できるような実装を作成できる

## 課題
システムと密接に関わりすぎて、前提が新規参画者と異なってしまう
システムを作ることが目的になってしまい、システムを運用していくことまで考えられていない

## 解消策
エンジニア界隈では有名なリーダブルコードを読んで、見やすいコード、改修しやすいコードとは何かを理解するところから始めようと思いました。

[<img width = 200 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2698022/edd3fe18-b141-62e9-3815-443d88d09388.jpeg">](https://amzn.asia/d/0KOIPKc)

## 対象者
コードを書くことに慣れてきたエンジニア🧑‍💻
新規開発に携わるエンジニア🧑‍💻
チーム開発を促進したいエンジニア🧑‍💻

## 1.理解しやすいコード
### 鍵となる考え：
他の人が最短時間で理解できるコード
### 1-1 短いコード = 理解しやすいコードではない：
``` javascript: Good Code🙆‍♂️
if (x > 0) {
    if (y > 0) {
        return 'x and y are both positive';
    } else {
        return 'x is positive but y is not';
    }
} else {
    return 'x is not positive';
}
```

``` javascript: Bad Code🙅‍♂️
return (x > 0) ? (y > 0 ? 'x and y are both positive' : 'x is positive but y is not') : 'x is not positive';
```

## 2.名前の選び方
### 鍵となる考え方
名前に情報を詰め込む

### 2-1. 明確な単語を選ぶ
#### 単語のバックグラウンドを考える
<dl>
<dt>例①：</dt>

```
getUrl()
```

</dl>

<dl>
<dt>検討：</dt>
URLはどこから取得してくるのだろう？
</dl>

<dl>
<dt>改善:</dt>

```
// DBの場合
selectUrl() or selectUrlFromDB()

// ローカルキャッシュの場合
getUrlFromCache()

// インターネットからの場合
fetchUrl()
```

</dl>

<dl>
<dt>
例②：
</dt>

```
size()
```

</dl>

<dl>
<dt>検討：</dt>
サイズは何のサイズを示しているのだろう？
</dl>

<dl>
<dt>改善:</dt>

```
// ウィンドウのサイズの場合
windowSize()

// input要素のサイズの場合
inputSize()

// バイナリファイルのサイズの場合
binarySize()
```

</dl>

### 2-2. tmpやretvalのような汎用的な単語を避ける
#### エンティティの値や目的を表すような単語にする
##### retval
```javascript: BadCode🙅‍♂️
function getFullName(lastName, firstName){
  const retval = lastName + firstName;
  return retval.replaceAll(' ', '');
}
```

```javascript: GoodCode🙆‍♂️
function getFullName(lastName, firstName){
  const fullNameWithBlank = lastName + firstName;
  return fullNameWithBlank.replaceAll(' ', '');
}
```

##### tmp
```javascript: BadCode🙅‍♂️
let tmp = userInfo.name;
tmp += ' ' + userInfo.phoneNum;
tmp += ' ' + userInfo.email;
```

```javascript: GoodCode🙆‍♂️
const BLANK = ' ';
const userInfo = userInfo.name + BLANK + userInfo.phoneNum + BLANK + userInfo.email;
```

### 2-3. 名前に情報を追加する
#### 絶対に知らせなければならない情報には「単語」を追加する

##### 16進数の文字列を持つ場合
```javascript: BadCode🙅‍♂️
const id = 'af84ef845cd8';
```

```javascript: GoodCode🙆‍♂️
const hexId = 'af84ef845cd8';
```

##### 時間を表す場合
```javascript: BadCode🙅‍♂️
// getTime()はミリ秒を返却するため、秒に変換する必要がある
const start = new Date().getTime();
const elapsed = new Date().getTime() - start;
console.log(elapsed + '秒');
```

```javascript: GoodCode🙆‍♂️
// 変数に単語を追加してミリ秒であることを強調する
const start_ms = new Date().getTime();
const elapsed_ms = new Date().getTime() - start_ms;
console.log((elapsed_ms / 1000) + '秒'); 
```

### 2-4. 名前の長さを決める
#### スコープに合わせて名前の長さを決める

##### スコープが小さい場合は短くても問題ない
```javascript: 
// 変数に単語を追加してミリ秒であることを強調する
const d = new Date();
```

#### プロジェクト固有の省略形を用いて名前を短くしてはいけない
```: BadCode🙅‍♂️
MLoginAttempts
```

```: GoodCode🙆‍♂️
MaxLoginAttempts
```

#### プログラマの中で共通認識がある単語は省略しても問題ない
```: GoodCode🙆‍♂️
string → str
document → doc
```

### 2-5. 名前のフォーマットで情報を伝える
#### フォーマット規約を作ることで名前に情報を詰め込む

##### コンストラクタ関数は大文字で、通常の関数は小文字にする
```
const datePicker = new DatePicker(); // コンストラクタ関数は大文字
const pageHeight = pageHeight(); // 通常の関数は小文字
```

##### jQueryは頭文字に$(ドルマーク)をつける
```
const $image = $('#image');
const height = 200;
```

## 3.コメント
### 鍵となる考え方
コメントの目的は、書き手の意図を読み手に知らせることである

### 3-1.コメントするべきでは「ない」こと
#### コードからすぐにわかることはコメントしない
##### 例)
```javascript: 適切ではないコメント🙅‍♂️
// Profileクラスの定義
class Profile {
    // コンストラクタ
    constructor(lastName, firstName){
        this.lastName = lastName;
        this.firstName = firstName;
    }

    // フルネームを返却する
    getFullName() {
        return this.lastName + ' ' + this.firstName;
    }
}
```

#### コードを理解するよりもコメントを見た方が早く理解できる場合はコメントする
```javascript: 適切なコメント🙆‍♂️
class Profile {
    constructor(lastName, firstName){
        this.lastName = lastName;
        this.firstName = firstName;
    }

    // ' Hello World! 'の場合は'Hello World!'になる。
    getFullName() {
        return trim(this.lastName + ' ' + this.firstName);
    }
}
```
#### コメントのためのコメントをしない
コメントをつけていない関数に罪悪感を抱き、関数の名前と引数をそのまま文章形式でコメントに書き込まない。
不要なコメントを書き込まない！！
```javascript: コメントのためのコメントをしない🙅‍♂️
// 姓・名を結合してコンソールにログを出力する
function getFullName(lastName, firstName){
    console.log(lastName + ' ' + firstName);
}
```

### 3-2.自分の考えを記録する
#### 「監督のコメンタリー」を入れる
映画監督が自分の考えや物語に関して熱く語ってくれることで作品の背景を知ることができるように、
コメントには、コードに対する大切な考えを記録しなければならない。

例①
```
// Controllerを追加するたびに、Configクラスにエンドポイントを追加する必要がある
```

例②
```
// このクラスは汚くなってきている。
// サブクラスを作成して整理した方がいいかもしれない。
```

#### コードの欠陥にコメントをつける
コードを今後改善する必要がある場合は、躊躇わずに以下のように書いておく
```
// TODO: もっと高速なアルゴリズムを使う
// TODO: JPEG以外のフォーマットに対応する
```

## まとめ
第一章はすぐにでも改善できるコード、コメントを紹介していたので、第二章以降でよりもっと深いところを学んでいくぜ！！👌