リーダブルコード　要約

# なにこれ
筆者がリーダブルコードを読んで、アウトプット用として書いてます！
独自で具体例を考えて記述している部分もあります。
解釈の間違いなど、不明点 or 懸念点がありましたら、コメントでご指摘いだだけますと幸いです！

# 1　理解しやすいコード
**コードは理解しやすくしろ！**

## 1−1「優れた」コードってなに？
簡潔か安心か。
三項演算子を頑張って使うか、if-else文で書くか。

## 1−2　読みやすさの基本定理
**他の人が最短時間で理解**できるコード
他の人とは、1年後の未来の自分かも知れない

短ければ良いけど、それより理解できるコードがどうか自問自答する

自分しか使わないコードでも、他の人が再利用して使うかも。
もしくは別のプロジェクトで使うかも。
だから怠慢にならず、しっかりと考えて書く。

# 2 名前の情報を詰め込む
別の言い方をすると、**変数名に情報を詰め込む**

## 2−1　明確な単語を選ぶ
例えば`get`はあまり明確な単語じゃない
**もっとカラフルな単語を探す**

**気取った言い回しよりも、明確で正確な方がいい。**

## 2−2　tmpやretvalなど汎用的な名前を避ける
`tmp, retVal, foo`
これらは数行だけで終わる短命な変数だけ使う

## 2−3　抽象的な名前よりも具体的な名前を使う
明確な単語を使う。抽象的な単語は使うな

## 2−4　名前に情報を追加する

## 2−5　名前の長さを決める

### スコープが小さければ、短い変数名でもおk
広く使う変数は、長くて良いから明確な名前にしてね。

### 省略形
例）
BackEndManager ➡️ BEManager

メリット：短い
デメリット：暗号みたいになる

新しくチームに来た人が理解できるならおk。ダメなら変えて。
書いた自分でも、後で見たら暗号に見えるかもだから。

### 不要な単語は消す

ConvertToStringをToStringにしても大きな問題はない！

## 2−6　名前のフォーマットで情報を伝える

# 3　誤解されない名前
**「他の意味と間違えられることはないか？」と何度も自問自答する**

## 3−1　filter
`filter`と`results`をセットで使う時は、何の結果なのか書いて！
選択するなら`select`、除外するなら`exclude`

## 3-2　clip
次の2つの見分けがつかない
・最後からlength文字を切り取る(remove)
・最大length文字まで切り詰め（truncate)

**lengthも良くない**
バイト数、文字数、単語数なのか分からん。
文字数なら、`max_length`より`max_chars`の方が適切

## 3−3　minとmax
限界値を含める時に使う

## 3−4　firstとlast
範囲を指定

## 3−6　ブール値の名前
常にtrueかfalseの意味を明確にしろ

read_password
上記の変数名はアンチパターン。次の2つの意味がある。
・これからパスワードを読む
・既にパスワードを読んでる

`is, has, can, should`などをつけろ。

変数名は否定形より肯定形にした方が読みやすい。
`dissable_ssl = false;`より`use_ssl = true`など
`NotFind = false`より`IsFind = true`みたいな？右側はぱっと思いつきだけど。

## 3−7　ユーザーの期待に合わせる
先入観を持ってコードを読んだ時に読み間違える場合がある。
その場合は名前を変えるのも有り

### get
getは簡単な処理と思い込まれてる。
それがもし重い処理だったら困る。
`get_avg_all_product`より`compute_avg_all_product`の方が良い

## 3−8　複数の名前を検討する

# 4　美しさ
コードは雑誌のように美しくあるべき。

そのために次の3つが必要
・読み手が慣れているパターンと、一貫性のあるレイアウトを使う
・似ているコードは似ているように見せる
・関連するコードをまとめてブロックにする

## 4−2　一貫性のある改行を心がける
・似たメソッドがある中で、1つだけ改行がずれてると違和感
・同じようなメソッドなら共通化できるか考える

```rb
wifi = Calc.new(
  hoge: 'fuga'
)
mobile_calc_now =
  Calc.new(
  hoge: 'fuga'
)

wifi = Calc.new(
  hoge: 'fuga'
)
mobile_calc_now = Calc.new(
  hoge: 'fuga'
)
```

## 4−3　メソッドを使った整列
見た目をよくすれば、コードの構造も改善できることがある！

## 4−4　縦の線を真っ直ぐにする

```rb
checkUser('yamada', 'tarou', 21)
checkUser('tani', 'kyoukomaru', 100)

checkUser('yamada', 'tarou'     , 21)
checkUser('tani',   'kyoukomaru', 100)
```

**Q.手間をかけても整列すべきか？**
**A.整列すべき！**
いちいち整列するのは面倒と思うけど、ほとんどのケースで対して負担にならない。

## 4−5　一貫性のある並び
並べる順番には気をつける。上から順に行くように

```js
details = request.POST.get('details')
url     = request.POST.get('url)
```

## 4−6　宣言をブロックにまとめる

## 4−7コードを段落に分割する

```rb
def bad_send_email
  friend = User.find(1)
  puts "comment"
  friend.save
end

def good_send_email
  friend = User.find(1)
  friend.save

  puts "comment"
end
```

## 個人的な好みと統一性

次の2つはどちらも差はないけど、このコードが混在すると理解に苦しむ。
なので、チームとして統一する書き方を決める

```js
class Logger {
  //
}

class Loger
{
  //
}
```

**一貫性のあるスタイルは、「正しい」スタイルよりも大切**

# 5　コメントすべきことを知る
**コメントの目的は、書き手の意図を読み手に知らせること**

## 5−1　コメントするべきでは「ない」こと
コードからすぐに分かることをコメントに書かない

### コメントのためのコメントをするな
コードから分かることはコメントするな

### ひどい名前はコメントを付けずに名前を変えろ

## 5−2　自分の考えを記録する

### 映画のコメンタリーのイメージ
なぜこのコードはこのやり方なのか？

・ここの処理は訳ありだ
・この変数名は100％の意味ではない
・このクラスは汚い。別のsubclassを作って分割した方が良い

### コードの欠陥にコメントを付ける
・`TODO`（大きな修正）
・`FIXME`（既知の不具合がある）
・`HACK`（あまり綺麗じゃない解決策）
・`XXX`（危険！大きな問題あり）

　**これからどうしたいかをコメントに書く**

### 定数にコメントを付ける
定数にまつわる背景

## 5−3　読み手に立場になって考える

他の人とは、**あなたほどプロジェクトを熟知していない人**のこと

### 質問されそうなことを想像する
コードを読んだ人が「え？」と思うところを予想してコメントする

###ハマりそうな罠を告知する
平均的な読み手が驚くような動作は文章化しておく

次の2つを考える。
・このコードを見て、びっくりすることは何だ？
・どんなふうに間違えて使う可能性がある？

### 全体像のコメント
・ソースコードを読んでも得られない情報のコメントなど
・短い文章でおk．何もないよりマシ

### 要約コメント
関数のブロックの処理ごとに書いてもおk。概要をまとめるイメージ
ただ重要なのは、**優れたコメントより優れたコード**

## 5−4　ライダーズブロックを乗り越える
とりあえず考えていることをコメントに書き出す

コメントを書く作業は3つに分割できる
1．頭の中にあるコメントをとにかく書き出す
2．コメントを読んで、改善が必要なものを見つける
3．改善する

やばい。これは面倒になる
⬇️
やばい➡️この処理は気をつけて。
これは➡️入力時にやると
面倒になる➡️実装の難易度が上がる。

# 6章　コメントは正確で簡潔に
**コメントは領域に対する情報の比率を高くしろ**

## 6−1　コメントを完結にしておく
3行で説明するより1行で簡潔に

## 6−2　あいまいな代名詞を避ける
「それ」や「これ」みたいな

## 6−3　歯切れの悪い文章を磨く

これまでクロールしたURLかどうかによって優先度を変える
⬇️
これまでにクロールしていないURLの優先度を高くする

## 6−4　関数の動作を正確に記述する

このファイルに含まれる行数を返す
⬇️
このファイルに含まれる改行文字`\n`を数える

## 6−5　入出力のコーナーケースに実例を使う

変数`src`の戦闘や行末にある`chars`を除去する
⬇️
strip(‘abba/a/ba’, ‘ab)は`’/a/‘を返す
⬇️
strip(‘ab’, ‘a’)は’b’を返す

長い説明コメントより、実例を交えて入出力の結果を書くと分かりやすい

## 6−6　コードの意図を書く

コメントは、コードを書く時に考えていることを読み手に伝えるためのもの
コードの意図は、詳細レベルより高レベルで記述する。
抽象度を上げるかは時と場による

listを逆順に居てレートする
⬇️
listを値段の高い順に表示する

## 6−7　「名前付き引数」コメント

```js
Connect(/* timeout_ms */ 10)
```

ややこしい引数だったりに使うと良いかも

## 6-8　情報密度の高い言葉を使う

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

**条件やループなどの制御フローは、できるだけ「自然」にする。コードの読み手が立ち止まったり読み返したりしないように書く**

## 7−1　条件式の引数の並び順

`if (length >= 10)`

| 左側 | 右側 |
| --- | --- |
| 調査の対象。変化する。 | 比較の対象。あまり変化しない。 |

## 7-2 if-elseブロックの並び順

・条件は否定形`if(!debug)`より`if(debug)`を使え
・単純な条件を先に書く。if-elseが同じ画面に表示されるので見やすい
・関心を引く条件や目立つ条件を先に書く。

「ピンクの象を考えないでください」現象と同じ。1回頭に入ると考えちゃうから、複雑な条件を書くな！

```js
if(!url('pink_zoo')) {
  p 'ng'
} else {
  p 'ok'
}

if(url('pink_zoo')) {
  p 'ok'
} else {
  p 'ng'
}
```

## 7−3　三項演算子
賛否あり。
**行数を短くするよりも、他の人が理解するのに掛かる時間を短くしろ**
頑張って1行で書かなくても良い。分かりやすさのほうが重要

```js
// good
time = (hour >= 12) ? 'pm' : 'am'
```

```js
// bad
time = if(hour >= 12) {
  'pm'
} else {
  'am'
}

// bad
return exp >= 0 ? man * (1 << exp) : man / (1 << -exp)

# good
return if(exp >= 0) {
  man * (1 << exp)
} else {
  man / (1 << -exp)
}
```

**基本的には`if/else`を使う。三項演算子で簡潔に書けそうならおk**

## 7−4　do/whileループを避ける
コードを2回読む必要があったり、下から上に移動して読む必要があるので使うな

## 7−5　関数から早く返す

## 7−6　悪名高きgoto

スパゲティコードになる。

## 7−7　ネストを浅くする

**修正する時はコードを新鮮な目で見る。一歩下がって全体を見る**
ネストを変える時は特に！

```js
// 初期
if(result1 == SUCCESS) {
  done()
} else {
  return
}

// 変更後（ややこしい）
if(result1 == SUCCESS) {
  if(result2 != SUCCESS) {
    return
  }
  done()
} else {
  return
}
done()
```

### 早めに返してネストを削除する

```js
if(result1 != SUCCESS) {
  return
}
if(result2 != SUCCESS) {
  return
}
done()
```
### ループ内部のネストを削除
ガード節を使ったり、continueをワンライナーで書いたりする。
返す条件を先に書くこと！
**直線的に分かるコードを書こう**

# 8　巨大な式を分割する

**巨大な式は、飲み込みやすい大きさに分割する**
人間は同時に3〜4のことしか考えられない。

## 8−1　説明変数

・（巨大な）式を分割できる
・簡潔な名前で式を説明することで、コードを文書化できる
・コードの主要な概念を読み手が認識しやすくなる

```rb
if params[:user_name] == 'root'

user_name = params[:user_name]
if user_name == 'root'
```

## 8−2　要約変数

```js
if (request.uesr.ud == document.owner_id) {
  // ユーザーはこの文章を編集できる
}
if (request.user_id != document.owner_id) {
  // 読み取り専用
}

user_owns_document = (request.uesr.ud == document.owner_id)
if (user_owns_document) {
  // ユーザーはこの文章を編集できる
}
if (!user_owns_document) {
  // 読み取り専用
}
```

## 8−3　ド・モルガンの法則を使う

```js
if(!(file_exists && !is_protected)) Error

if(!file_exists || is_protected) Error
```

## 8−4　短絡評価の悪用

**「頭がいい」コードには気をつける。後で他の人（未来の自分含む）が読む時にわかりにくくなる**
1行で収めることが素晴らしいことじゃない！！
2行になっても最短時間で理解できる方が重要！

## 8−5　複雑なロジックと格闘する

```js
return (begin >= other.begin && begin < other.end) ||
       (end > other.begin && end <= other.end)

if(other.end <= begin) return false // 一方の終点が、この始点よりも前にある。
if(other.begin >= end) return false // 一方の始点が、この終点よりも後になる
return true
```

##  8-6　巨大な式を分割する

```js
if($("#vote_value").html() === "Up") {
  $("#thumbs_up).addClass("highlighed")
  $("#thumbs_down).removeClass("highlighed")
} else if($("#vote_value").html() === "Down") {
  $("#thumbs_up).removeClass("highlighed")
  $("#thumbs_down).addClass("highlighed")
}


let thumbs_up = $("#thumbs_up")
let thumbs_donw = $("#thumbs_down")
let vote_value = $("#vote_value")
let hi = "highlighed"

if(vote_value.html() === "Up") {
  thumbs_up.addClass(hi)
  thumbs_down.removeClass(hi)
} else if("vote_value").html() === "Down") {
  thumbs_up.removeClass(hi)
  thumbs_down.addClass(hi)
}
```

## 8−7　四季を完結にするもう1つの創造的な方法

# 9　変数と読みやすさ

変数を雑に使うと起きる問題
・変数が多いと、変数を追うのが難しい
・変数のスコープが大きいと、スコープを把握する時間が長くなる
・変数が頻繁に変更されると、現在の値を把握するのが難しい

## 9−1　変数を削除する

**邪魔な変数を削除する**

### 役に立たない一時変数

次のコードの問題
・複雑な式を分割してない
・より明確になっていない。Date.nowでも伝わる
・一度しか使ってないので、重複コードの削除になっていない

```rb
now = Date.now()
message.created_at = now

message.created_at = Date.now()
```

#### 私的メモ
すごいあるあるだと思ったので、こういったコードがないか見直す習慣をつける
逆に見つけられるようになる

### 中間結果を削除する
**タスクはできるだけ早く完了するほうが良い**

```js
let remove_index = null
for (let i = 0; i < array.length; i++) {
  if (array[i] === null) {
    remove_index = array[i]
  }
  if (remove_index !== 0) {
    array.splice(remove_index, 1)
  }
}

for (let i = 0; i < array.length; i++) {
  if (array[i] === null) {
    array.splice(i, 1)
    return
  }
}
```

### 制御フロー変数を削除する

制御フロー変数は、ほとんどの場合でうまくプログラミングすれば削除できる。

```js
done = false // 制御フロー変数
while(!done) {
  if(処理) {
    done = true;
    continue
  }
}

while (処理) {
  if(処理) {
    break;
  }
}
```

面接時には変数が3つ以上あると言われてる。
コードを読む時に変数が3つ以上あったら、常に面接を受けるのと同じ心意気になってしまう。そんな思いをさせたいか？

## 9-2　変数のスコープを縮める

**すべての変数のスコープを縮めるのは良いこと**
**変数のことが見えるコード行数をできるだけ減らす**

・ミニグローバル変数をローカル変数に格下げする

### JavaScriptのプライベート変数

```js
submitted = false // グローバル変数

let submit_form = function(){
  if(submitted) {
    return // 2重投稿させないため
  }
  submitted = true
}


let submit_form = (function(){
  submitted = false // グローバル変数

  return function(){
    if(submitted) {
      return // 2重投稿させないため
    }
    submitted = true
  }
}()) // 即時関数でプライベート化
```

### JavaScriptのグローバルスコープ
letなどをつけずに変数を定義すると、グローバル変数になる？今はそもそも定義できない気がする

#### 私的メモ
だからvueだとlet or constがないとエラーを吐くのかな？

# 9−3　変数は一度だけ書き込む
constなどイミュータブルな変数を使えば、コードが理解しやすくなる

**変数を操作する場所が増えると、現在地の判断が難しくなる**
Javaの作者いわく、イミュータブル（不変）はトラブルが少なくなる傾向

## 9-4　最後の例

中間変数を消して、すぐに返す。
elemの代入回数が多かったので、1回にして置いやすくした。

```js
let setFirstEmptyInput = function(new_value) {
  let found = false
  let i = 0
  let elem = document.getElementById('input' + i)
  while(elem !== null) {
    if(elem.value === ''){
      found = true
      break
    }
    i++
    elem = document.getElementById('input' + i)
  }
  if(found) elem.value = new_value
  return elem
}


let setFirstEmptyInput = function(new_value) {
  for(let i = 0; i < 4; i++) {
    elem = document.getElementById('input' + i)
    if(elem.value === null) {
      return null
    }
    if(elem.value === '') {
      elem.value = new_value
      return elem
    }
  }
}
```

# 10　無関係の下位問題を抽出する
**無関係の下位問題を積極的に見つけて抽出する**

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

## 10−1　入門的な例
すごいざっくり言うと次の例。
メソッド内の別の処理を、他のメソッドに切り分けること。
これが下位問題

```rb
def puts_result
  a = 1
  b = 2
  result = a * b
  puts result
end


def addition(num1, num2)
  num1 * num2
end

def puts_result
  a = 1
  b = 2
  result = addition(a, b)
  puts result
end
```
## 10−2　純粋なユーティリティーコード
「この関数ないなあ」と思った時には、作れば良い！
それが他でも使いまわせる。

## 10-3　その他の汎用コード
### 思いも寄らない恩恵
関数は、小さくて独立したものになっていれば、機能追加、読みやすさの向上、エッジケースの処理などが楽にできる！
例外の処理を切り分けたりも楽。

## 10−4　汎用コードをたくさん作る
プロジェクトから完全に切り離されているコードは3150！
メンテしやすい・影響を与えないことでコードが短く保てる！

**大事なのは、下位問題を分離して処理できるか**

## 10−5　プロジェクトに特化した機能
下位問題を取り除くだけでも効果あり！

## 10−6　既存のインターフェースを簡潔にする
**理想とは程遠いインターフェースに妥協することはない。**
自分でラッパー関数を用意して、汚いインターフェースを覆い隠せ！

## 10−7　必要に応じてインターフェースを整える
多くのコードはその他のコードを支援するためだけに存在する。
例えば、関数の事前処理や事後処理。
こういう**グルーコード**は、プログラムの本質的なロジックと関係ないことが多い。

## 10−8　やりすぎ
小さな関数を作りすぎると、逆に読みにくくなる。（当たり前だけど）

# 11　一度に1つのことを
**コードは1つずつタスクを行うようにしろ**

### 一度に1つのタスクをするために使ってる手順
1．コードが行ってるタスクをすべて列挙する。タスクは「オブジェクトが妥当かどうか」や「ツリーのすべてのノードをイテレートする」など曖昧~~（アイマイミーマイン）~~

2．タスクをできるだけ異なる関数に分割。少なくとも異なる領域に分割する

## 11−1　タスクは小さくできる
### 一度に1つのタスクを適用する

# 12　コードに思いをこめる

おばあちゃんに説明して分かるぐらい。

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

## 12−1　ロジックを明確に説明する

## 12-2　ライブラリを知る

# 13　短いコードを書く

**最も読みやすいコードは、何も書かれていないコード**

なるべく新しいコードを書かずに、ライブラリのコードを使う。
ライブラリのコードは素晴らしい。緻密に練られたコードだから。
エンジニアが1日に書く**出荷用**のコードは、平均10行！

定期的に組み込みライブラリの一覧を見て、使えそうなライブラリがないか頭にインデックスを作れ！

新しいコードを書くと、その分テスト・文書化・保守が必要になり、プロジェクトが**重たく**なり、開発も難しくなる。

新しいコードを書かない3つの原則
・不必要な機能をプロダクトから削除する。過剰な機能は持たせない
・最も簡単に問題を解決できるような要求を考える
・定期的に全てのAPIを読んで、標準ライブラリに慣れる

# 14　テストと読みやすさ

## 14−1　テストを読みやすくて保守しやすいものにする
**他のプログラマが安心してテストの追加や変更ができるように、テストコードを読みやすくする**

テストコードが大きくて恐ろしいことの弊害
1．本物のコードの修正を恐れる
2．新しいコードを書いた時にテストを追加しなくなる

## 14−3　テストを読みやすくする
**大切ではない詳細はユーザ（自分含む）から隠し、大切な詳細は目立つようにする**

テスト失敗時には、失敗した時の値が出力されるとデバックしやすい！確かに。

**コードを完全にテストする、最も単純な入力値の組み合わせを選択しろ！**
（テストは最もキレイで単純な値を選べ）

### 一つの機能に複数のテスト
1度ですべての項目をテストするんじゃなくて、複数回に分ける。
その方がデバッグしやすく読みやすい。他の人も修正しやすい。

assertだと失敗分がそのまま表示される。独自でエラー文を作るのも良いかもね！

## 14−9　やりすぎ
**・テストのために本物のコードの読みやすさを犠牲にしてしまう**
本末転倒

**・テストのガバレッジを100％にしないと気がすまない**
コードの90％をテストする方が楽。
残りの10％の多くは、ユーザインタフェースやどうでもいいエラーケースがほとんど。
コストが高くないので、わりに合わない！

**・テストがプロダクト開発の邪魔になる**
プロジェクトの一部にすぎないテストのはずが、プロジェクト全体を支配してることがある。テストを書くのが儀式になってる。

## 14−10　まとめ
・テストのトップレベルはできるだけ簡潔にする。入出力のテストはコード1行で記述できるとおk
・テストが失敗したら、バグの発見や修正がしやすいようなエラーメッセージを表示する
・テストは有効で最も単純な入力値を使え！
・テスト関数は長くてもおk。他で呼び出すことはないからね！ほぼ説明文でも良い

特に新しいテストの追加や修正を簡単にすることが大切。