「リーダブルコード」から得た実践的知識まとめ

# はじめに
エンジニアにとっての”バイブル”とも呼べる「リーダブルコード」。
今回は復習も兼ねて、まだ読んだことのない方に向けて内容を簡単にまとめてみました。
この本は何度でも読み返すべきオススメの一冊なので、まだ読んだことがない方はぜひ実際に本を手にとって読んでみてください。

https://amzn.asia/d/0XWwNjM

すでに読まれた方にとっては、内容を思い出すきっかけとなれば幸いです。


# コードは「他人」が最短時間で「理解」できるように書く
コードは短くリファクタリングしたほうがいい。しかし、それ以上に「理解するまでにかかる時間」を短くするほうが大切。
・ここでの「他人」には、”未来の自分”も含まれている。
・ここでの「理解」とは、変更を加えたりバグを見つけたりできるという意味。

```typescript:短く簡潔だが、理解が難しいコード例
const fizzBuzz = (n: number) =>
  Array.from({ length: n }, (_, i) => (++i % 3 ? "" : "Fizz") + (i % 5 ? "" : "Buzz") || i);
```

```typescript:長いが、理解がしやすいコード例
//1から指定された数値nまでの数を処理し、3の倍数なら"Fizz"、5の倍数なら"Buzz"、
//3と5両方の倍数なら"FizzBuzz"、それ以外の場合はその数値を、配列にして返す関数
const fizzBuzz = (n: number): Array<string | number> => {
  const result: Array<string | number> = [];
    
  // 1からnまで順にループ
  for (let i = 1; i <= n; i++) {
    if (i % 3 === 0 && i % 5 === 0) {
      result.push("FizzBuzz"); // 3と5の倍数
    } else if (i % 3 === 0) {
      result.push("Fizz"); // 3の倍数
    } else if (i % 5 === 0) {
      result.push("Buzz"); // 5の倍数
    } else {
      result.push(i); // それ以外の数値
    }
  }
  return result;
}
```

```typescript:結果はどちらも一緒
console.log(fizzBuzz(15));
console.log(generateFizzBuzz(15));

[1, 2, "Fizz", 4, "Buzz", "Fizz", 7, 8, "Fizz", "Buzz", 11, "Fizz", 13, 14, "FizzBuzz"]
```


# 名前に可能な限りの情報をつめこむ
変数名や関数名、クラス名やファイル名、などなど。名前をつける際には的確な情報をつめこむ。
`const getPage()`（悪い例）
`const getTopPageFromAPI()` （良い例）

### 1. より明確な単語を選ぶ
`getData()`よりも`fetchData()`や`downloadData()`、
`stop()`よりも`kill()`や`pause()`を使ったほうが、どんな関数なのかが想像しやすい。

### 2. 汎用的な名前を避ける
`result = `よりも`sum_squares = `のほうが、どんな値を持つ変数なのかをイメージできる。
（例外）
２つの変数の値を入れ替える際に使う`tmp = `は”ただの一時的な入れ物”という意味が込められているのでそのままがよい。

### 3. ループ処理のイテレータ変数
```typescript
for (let i = 0; i < orange; i++) {
    for (let j = 0; j < banana; j++) {
      for (let k = 0; k < apple; k++) {
        array.push([i, j, k]); // i, j, kの現在の値を配列に追加
      }
    }
  }
```
上記のような場合は、`i, j, k`を使うよりも単語の頭文字から`oi, bi, ai`を使うほうがミスを減らせる。

### 4. 重要な属性を追加する
`password = `ではなく`plaintext_password = `とすることで、後で暗号化する処理を忘れずにすむ。
`size_mb = `や`sleep_ms = `のように、単位に複数の可能性がある場合は明確にする。


### 5. ブール値の名前
ブール値を返す関数や、ブール値を持つ変数の名前は、疑問形で"Yes,"もしくは"No,"で答えられる`is, has, can, should`を先頭につけるとわかりやすい。
(例)
`isAdmin = false`
`canReserve = true`


# コメントすべきことを知る
大前提として、通常は「補助的なコメント」が必要になることはない。（そういうわかりやすいコードを書くべき）
`優れたコード　>　ひどいコード　+　優れたコメント`
コメントを書くと、その分だけコードを読む時間は長くなってしまう。そのため、コメントには存在するべき価値をもたせるべき。
```typescript:価値のないコメント
//新しいスタートタイムを設定する
start_time = setStartTime()
```

```python:価値のあるコメント
# 2番目の'*'以降をすべて削除する
name = '*'.join(line.split('*')[:2])
```


### 1. その瞬間の自分の考えを記録する
(例)
`//いろんなソートを比較してみた結果、このソートが最適だった`
→　このコメントがあれば下手に最適化しようとして時間を無駄にしなくてすむ

`//このmodelファイルには関係のない関数が多くあるので、helper関数ファイルに移動させたほうがいいかも`
→　初めてこのファイルを読む人が悩まずにすむし、誰かに修正を促している。


### 2. 修正箇所にコメントをつける
(例)
`//TODO(田中さん):多言語に対応する`
`//maybe-later:もっと高速なアルゴリズムを使う`

### 3. 定数にコメントをつける
(例)
`capacity = 15 //今回のイベントは一度に入場可能な人数が最大15人`
`ratio = 0.72 //いろいろ試した結果、この比率が一番キレイだった`

### 4. 呼び出す際に注意が必要な関数にコメントをつける
(例)
```
//メールを送信する外部サービスを呼び出している（1分でタイムアウト）
const sendEmail = (path: string, subject: string, body: string): void => {
```

### 5. ファイルにコメントをつける
(例)
`//このファイルには管理者権限を操作するためのヘルパー関数が含まれています。`
`//このファイルは「注文確認ページ」のbuttonコンポーネント`



# おわりに
読み進める中で、「コードを書く目的は、人間が読んで理解できること」という著者の主張が何度も強調されており、深く納得しました。
この本を読んだことで、自分のコードを書く際の姿勢が変わり、より他者を意識した設計を心がけるようになりました。

この「リーダブルコード」は、全3部構成で、合計15章から成り立っています。
章立ては「難易度」の順番になっていて、読み進めていくほど応用的な内容となっています。
今回は、第一部「表面上の改善」の内容を取り上げてみました。

第二部「ループとロジックの単純化」、第三部「コードの再構成」の内容に関しては、リファクタリングについて書かれたこちらの記事が参考になるかと思います。

https://qiita.com/genimura/items/08d4d86818249d511d73