読みやすいコードを書こう（１、基本方針）

# 概要

### 書いた人
ヤマシタ
[積木製作](http://tsumikiseisaku.com/)の新人エンジニア
Twitter : [@AtsushiYama505](https://twitter.com/AtsushiYama505)

### この文章を書いた理由
 社内のコード品質を高めるため、研修に使うドキュメントとして書きました。

### この文章の対象
読みやすいコードをこれから書けるようになりたい方
エンジニアに「このコード読みにくい」と言われてイラっとした方
とりあえずサクッと、コードの可読性を高めたい方（チェックシートとしてどうぞ）
などなど。。。

### 免責
可読性を高めるという点において、
できるだけ議論の余地が少ないトピックをまとめているつもりです。
ただ、本の内容を受け売りして、
自分の修行不足などで誤解している箇所があるかもしれません。
そのような場合はそっと教えてください。こっそり修正します。

# なぜ読みやすいコードが必要か
### 実は最初に身に着けるべき技術
プログラムにおけるソースコードは「機会と人間が読むもの」です。
そのため、読みやすい文章を書く技術は、
時にプログラムそのものを書く技術より優先度が高いものとなります。

初心者の人だと
「読みやすいコードは上級者向けだから、今の自分には関係ない」なんて思うかもしれません。
しかし、本当は初心者に近いほど、読みやすいコードが重要となります。


### 修正しやすいコード
プログラミングそのものが目的の人は別ですが、
何らかの手段や道具として使っている場合、
「プログラムを作る」という行為は
「プログラムを修正（メンテナンス）する」という行為とセットになります。

つまり、「後で読み直して修正しやすいコードを書く」事から逃げると、
後から「なんでこんなコードを書いたのか」と頭を抱えることになるわけです。

また「読みやすくても遅いコードじゃ意味がない」という人もいますが、
修正しやすいコードにすれば、あとからいくらでも早いコードに書き直せます。
この書き直しは土台の上に家を作るような作業ですが、
後から読めないコードを修正するのは土台から作り直すような作業になります。
基本的に、修正しやすいコードを書くように心がけましょう。

### 書く時間より読む時間の方が長い
また、一般的にソースコードは書く時間より読む時間の方が長くなります。
仕事で使うコードなら自分以外の人にも読んでもらうことになり、
「読む時間＝理解する時間×チェックする人数」という形で爆発的に増えていきます。
読みやすいコードを書かない人は周囲の人の時間泥棒でもあるわけです。


# 読みやすいコードとは
### 動作を保証できる範囲
プログラムを書いていて、
一度もバグに遭遇したことがないという人はいないでしょう。

「バグ」というと虫みたいに湧いてでるんだから仕方ないという気になりますが、
「作者が意図通りにできなかった動作」と言うと、
もうちょっと最初から、意図した通りの動作が書けるようになりたくなると思います。

この「意図通りにできなかった」というのは、
「意図した動作を保証できる範囲から飛び出した」と言い換えてもいいです。
つまり、動作が保証できる範囲で書くことができれば、
バグのないコード、意図したとおりのコードが書けるわけです。
全体の中で、この範囲が大きいほど良いのは間違いないです。

### 範囲を確保する

ではどうやったら動作保証の範囲を大きく確保できるか。
それが「読みやすいコードを書く」ことであり。
「読んでいて間違いがわかりやすいように書く」ことです。

あいまいな判定や、複雑な処理、ネストの深い構造などは、
意図した動作にならない状況の原因になります。
機械であるコンピュータにとって読めるコードでも、
人間である私たちには、動作保証が難しくなるわけです。

こうした「動作保証範囲から出てしまう原因」を徹底的に減らすことが、
結果的に読みやすいコードを書くことにつながります。



# 基本的な指針
### 塊を切り分ける
人間の脳みそが持っている作業領域は、あまり大きくありません。
[ワーキングメモリ - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%AF%E3%83%BC%E3%82%AD%E3%83%B3%E3%82%B0%E3%83%A1%E3%83%A2%E3%83%AA)
つまり「一度に把握するべき範囲が小さいほど良い」わけです。
大きなクラスや関数は徹底的に分割しましょう。

### 混雑を整理する
プログラムの基本は「順番に実行する」「繰り返す」「分岐する」です。
この時、いくつもの分岐を一つの関数にまとめて書いてしまったりしていないでしょうか。
`AかつBかつCまたはnotAかつDかつnotEの場合`みたいな分岐について、
それが「本当に意図した通りに動くことがわかりやすく表現されている」と言える状態になっているでしょうか。
また繰り返しも潜在的に「一定の数以下なら」「ここからここまでなら」という条件を含んでいます。
二重、三重になった分岐や繰り返しは、多くの場合バグの原因です。
関数を分けたり、条件の論理を整理したり、
分かりやすく書くための技術はいろいろあります。


### 小さなものを使う
大きなプログラムは小さな部品の組み合わせでつくりましょう。 [^1]
例えば文章の中で特定のものを置き換えるプログラムを書く場合、
「特定の文字を探すして場所を取得する」「取得した場所の文字を削除する」「取得した場所に文字を追加する」と、
こうした三つの「働き」をまとめて書くのは望ましくありません。

それぞれ別の部品として書いて組み合わせれば、様々なシーンで使いまわしできますし、
動作が保証できていなかったのがどこか、事前に切り分けておいた方が確認しやすいのもわかるでしょう。

### 責任を限定する
人間にとって簡単なことを、わざわざプログラムでやる人はほとんどいないでしょう。
人間にとって難しくて、機械にとって簡単なことを任せる。そのためのプログラムです。
こうした条件から、大体は「大量のデータを正確に処理する」プログラムとしてその手順を書くわけです。
その時に大切なのはできる限り「一度にまとめて処理しようとしない」「いくつにも分割する」ことです。
その小さなプログラムが関与する範囲、結果に責任を持つ範囲を限定するわけです。
こうすることで、問題が発生したときに、その問題の結果から原因を簡単に推測できるようになるわけです。

### 正しく名前を付ける
人間は物事をとらえるときに、名前を付けます。
例えばリンゴというもの一つでも、たくさん連想できるものがあるはずです。
「青りんご」「熟したリンゴ」「腐ったリンゴ」「リンゴの樹」「リンゴの果実」「リンゴの種」などなど。。。
「Apple」という変数を見て、その動作をどう保証するのでしょうか。
動作を保証するのが読みやすいコードを書く目的の一つだと思い出して、
特徴をとらえた良い名前を付けるようにしましょう。
また、この名前を上手につけることで、上述した責任の限定をより生かすことができます。
（Appleクラスでトマトの情報を扱っていたら、これは「どう考えてもおかしい」ですからね）

### 抽象化してまとめる
オブジェクト指向についての本を読むと、多態性（ポリモーフィズム）についての説明があると思います。
これは非常に便利な機能で、例えば「オーボエもタンバリンも楽器の一種で、音を鳴らせる」というような特性をもとに、
その特性で処理をまとめてしまうことができます。
これを上手に使うことで、何百種類もの楽器それぞれのコードを読まないでも、
継承元のコードを読むことで基本的なふるまいを把握することができるわけです。
（オブジェクト指向についてはいずれ解説を書きたいと思います。。。いつになるか。。。）

### ルールを定める
名前の付け方や、式の書き方、インデントの数などにはいろいろな流儀があります。
大切なのは「どのルールを使うかを決めて、それを守ること」です。
同じプロジェクトの中で複数のルールが混在していると見間違えの元になります。
会社であればチームリーダーや組織の文化でルールが決められていると思います。
個人の開発ルールが無い場合は少しずつルールをきめていきましょう。
代表的なものに「名前の付け方」「ファイルごとの行数」「文字数」「括弧の位置」「ライブラリの強制」「コメントの付けかた」などがあります。
もちろん「読みやすいコードを意識する」なども重要なルールです。
また、こうしたルールが正しく守られているか確認する道具としてlinterというものがあります。
lintとはほつれのことで、名前通りにソースコードの「ルールほつれ」を見つけて知らせてくれます。
C#であれば[StyleCop](https://github.com/StyleCop/StyleCop)や[SourceMonitor](http://www.campwoodsw.com/sourcemonitor.html)、[ReSharper](https://samuraism.com/jetbrains/resharper)などが定番でしょう。
JavaScriptであれば[JSLint](https://www.jslint.com/)は鉄板。
Rubyであれば[ruby-lint](https://github.com/YorickPeterse/ruby-lint)でしょうか。
こうしたソフトを使うことで、読みやすさの品質を確保できます。

### 仲間を想う
読みやすいコードを書く時の、一番の指針がこれです。
自分が読めるのは当たり前ですが、そのコードを仲間が読むことはできるでしょうか。
一人で開発しているとしても、今日の自分と三か月後の自分は別人で、チームメイトな関係です。
もし三か月後の自分を殺したいほど憎んでいるのでもなければ、
できるだけコメントを残して分かりやすく書くことを意識しましょう。



[^1]: 小さな力で大きな効果、てこの原理とも。[UNIXという考え方―その設計思想と哲学(Amazon)](https://www.amazon.co.jp/UNIX%E3%81%A8%E3%81%84%E3%81%86%E8%80%83%E3%81%88%E6%96%B9%E2%80%95%E3%81%9D%E3%81%AE%E8%A8%AD%E8%A8%88%E6%80%9D%E6%83%B3%E3%81%A8%E5%93%B2%E5%AD%A6-Mike-Gancarz/dp/4274064069/ref=sr_1_1?ie=UTF8&qid=1526993853&sr=8-1&keywords=unix)