リーダブルコード覚え書き

## 経緯
- およそ7年前にも読んだことがある
- その時の感想。「普通の当たり前のことが書いてあるな」
- 仕事でコードレビューをする機会が多くなる
- コードレビュー大変さを知る。同時に読みやすいコードの大切さを実感する
- 読みやすさとは？
- もう一度、リーダブルコードを読もう
- 何度も見返せるようにポイントをまとめる

## 第1章 読みやすさの基本原理
- 他の人が最短時間で理解できること
- 理解するのに時間が短縮されれば生産性も上がる

# 第Ⅰ部 表面上の改善

## 第2章 名前に情報を詰め込む

- 変数名は短いコメントだと思え
- 曖昧な単語は避け、明確で正確な名前をつける
- 「カラフル」な単語を探す。状況に合わせて適切な単語を選ぶ。  

```shell
send: deliver, dispatch(発送する), announce, distribute, route(発送する)  
find: search, extract, locate, recover(取り出す)  
make: create, set up, build, generate, compose(構成する), add, new
```

- `tmp` や `retval` などの汎用的な名前を避ける
- でも本当に `tmp` (生存時間が数行の一時的な情報の保管)なら tmp でも全然良し
- スコープが短ければ短い変数名（1文字とか）でも良い。逆にスコープが大きい場合は、短い名前はNG
- ループイテレータのインデックス `i`, `j`, `k` も複数のイテレータがある場合は説明的な名前にするよ良い ( `club_i`, `members_i`, `users_i` )

```js
if (clubs[club_i].members[members_i] == users[users_i]) {
```

- 汎用的な名前を使われているのは、ほとんど怠慢。少しだけでも時間を使って名前を考える習慣を
- 変数名に大切な情報を追加する。ミリ秒を表す変数名には後ろに _ms をつける
- 不要な単語は省略。`convertToString()` は `toString()` で十分伝わる
- 大文字やアンダースコアに意味を含める。クラスのメンバ変数にアンダースコアをつける `offset_`
 
## 3章 誤解されない名前

- `filter`, `length`, `limit` など曖昧な単語を使用しない
- `filter` => `select` (選択する) or `exclude` (除外する)
- `clip` => `remove` (最後) or `truncate` (周辺を除去)
- `length` => `max_length`
- 限界値を含める時は `max`, `min`
- 包含的範囲は `first`, `last`
- 包含/排他的範囲は `begin`, `end`
- bool値は頭に `is`, `has`, `can`, `should`

## 4章 美しさ

コードを読みやすくするための余白・配置・順序についての３つの原則  

##### 1. 読み手が慣れているパタンと一貫性のあるレイアウトを使う

- これはLintに任せる

#####  2. 似ているコードは似せてるように見せる

- 複数のコードブロックで同じようなことをしていたら、シルエットも同じようにする  
例）同じ処理をしている箇所をメソッドにまとめる

- 「見た目をよく」することで表面上の改善だけでなく、コードの構造の改善にもなる

##### 3. 関連するコードをまとめてブロックする

- 宣言をブロックにまとめる
- コードを段落に分割する。空行を使って大きなブロックを論理的な「段落」に分ける

## 5章 コメントすべきことを知る

#### コメントすべきでない

- コードからすぐに抽出できるコメント
- ひどい変数や関数の名前はコメントをつけずに名前を変える

#### 記録すべき自分の考え

- なぜコードが他のやり方ではなくこうなっているのか
- コードの欠陥に記法を使って示す `FIXME:` `TODO:`
- 定数にコメントする。マジックナンバーにまつわる背景。

#### 読み手の立場になって考える

- 質問されそうなことを想像する
- ハマりそうな罠を告知する
- 平均的な読み手が驚くような動作は文書化しておく
- ファイルやクラスには「全体像」のコメントを書く
- 読み手が細部に捕われないように、コードブロックにコメントをつけて概要をまとめる

## 6章 コメントは正確に簡潔に

- 複数の物を指す可能性がある「それ」や「これ」などの代名詞を避ける
- 関数の動作はできるだけ正確に説明する
- 入出力のコーナーケースに実例を使う
- コードの意図は、詳細レベルではなく、高レベルで記述する
- よくわからない引数にはインラインコメントを使う `Funciton(/* arg = *? ...)`
- 多くの意味が詰め込まれた用語や表現を追加って、コメントを簡潔に保つ

# 第Ⅱ部 ループとロジックの単純化

## 7章 制御フローを読みやすくする

- 条件式の並び順は、左側「調査対象」の式。変化する。右側「比較対象」の式。あまり変化しない。
- 英語の文章として自然な感じで

```javascript
Good
if (length >= 10)

while (bytes_received < bytes_expected)
```

```javascript
Bad
if (10 <= length)

while (bytes_expected > bytes_received)
```

## 8章 巨大な式を分割する

- **説明変数**：式の意味を説明してくれる変数

```javascript
Before
if line.split(':')[0].strip() == "root": 
```
```javascript
After
username = line.split(':')[0].strip()
if username == "root": 
```

- **要約変数**：大きなコードの塊を小さな名前に置き換えて、管理や把握を簡単にする変数

```javascript
Before
if (request.user.id == document.owner_id) {
// ユーザはこの文書を編集できる
}

if (request.user.id != document.owner_id) {
// 文書は読み取り専用
}
```

```javascript
After
const user_owns_document = (request.user.id == document.owner_id);

if (user_owns_document) {
// ユーザはこの文書を編集できる
}

if (!user_owns_document) {
// 文書は読み取り専用
}
```

- **短絡評価の悪用**

```c
Before
assert((!(bucket = FindBucket(key))) || !bucket->IsOccupied());
```

たった１行のコードだけど、しばらく立ち止まって考えなきゃいけない感じ。

```c
After
bucket = FindBucket(key);
if (bucket != NULL) assert(!bucket->IsOccupied());
```

全く同じものだけど、ずっと理解しやすくなった。

## 9章 変数と読みやすさ
- **中間結果の変数を削除する**
- **制御フロー変数を削除する**  
- **変数のスコープを縮める。** クロージャ（JS）を使って、プライベート変数を作る
- **変数定義の位置を下げる。** 関数の先頭に変数定義をまとめるのではなく、変数を使う直前に移動する

# 第Ⅲ部 コードの再構成

## 10章 無関係の下位問題を抽出する

- **無関係の下位問題を積極的に抽出して見つけて抽出すること**

1. 「このコードの高レベルの目標は何か？」と自問
2. 「高レベルの目標に直接的に効果があるのか？あるいは、無関係の下位問題を解決しているのか？」と自問
3. 無関係の下位問題を解決しているコードが相当量あれば、それらを抽出して別の関数にする。

- 抽出された関数は完全に自己完結しているので、自分がどのように使われているか知らない。再利用性が高い
- 純粋なユーティリティコード
- 抽出されたコードが独立していれば、そのコードの改善が楽になる
- インタフェースが複雑なライブラリはラッパーしてシンプルにする
- やりすぎ注意。小さな関数を作りすぎて、実行パスがあっちこっちに行って逆に読みにくくなる

## 11章 一度に１つのことを
- コードをデフラグする
- 一度に複数のことをするコードは理解しにくい
- コードは１つずつタスクを行うようにしなければいけない
- 「関数は一度に１つのことを行うべき」という考え方と同じ
- 読みにくいコードがあれば、そこで行われているタスクを全て列挙する
- そのタスクごとにコードを分割する

**コードのデフラグイメージ図**
<img width="400" alt="コードのデフラグ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49022/c78d1ce0-70bc-0a53-fd62-c55c8aae2beb.png">

## 12章 コードに思いを込める

- **おばあちゃんにがわかるように説明できなければ、本当に理解したとは言えない --アルバート・アインシュタイン**
- コードを簡単な言葉で説明する

1. コードの動作を簡単な言葉で同僚にもわかるように説明する 
2. その説明の中で使っているキーワードやフレーズに注目する
3. その説明にあわせてコードを書く

- 問題や設計をうまく言葉で説明できないのであれば、何かを見落としているか、詳細が明確になっていないということ
- プログラム（あるいは自分の考え）を言葉にすることで明確な形になる
- 説明で使っている単語やフレーズをよく見れば、分割する下位問題がどこにあるかわかる

## 13章 短いコードを書く

- **最も読みやすいコードは、何も書かれていないコードだ**
- 不必要な機能をプロダクトから削除する。過剰な機能は持たせない
- 最も簡単に問題を解決できるような要求を考える
- 定期的にすべての API を読んで、標準ライブラリに慣れ親しんでおく
- ライブラリの再利用
- 車輪の再発明をしない

## 14章 テストの読みやすさ
- 新しいテストの追加や
- テストのトップレベルはできるだけ簡潔にする。入出力のテストはコード１行で記述できるとよい
- テストが失敗したらバグの発見や修正がしやすいようなエラーメッセージを表示する（適切なアサーション関数を使用する）
- テストに有効な最も単純な入力値を使う
- テスト関数に説明的な名前をつけて、何をテストしているのかを明らかにする

## 15章 「分/時間カウンタ」を設計・実装する
- 時間バケツの実装は読むだけでは理解できなかった
- 自分でコードを書いてみると良いと思う

## 参考
[リーダブルコード](https://www.amazon.co.jp/dp/4873115655)