コーディング美学

# コーディング美学

[総コン Advent Calendar](https://adventar.org/calendars/2584) 18日目です(大遅刻)

[1日目](http://tkw.hateblo.jp/entry/readable_coza_afterword)がリーダブルコードについて書いていたので，私もプログラミング設計周辺の心得についてだらだら語っていきます．

## はじめに

あなたは、ソースコードを書けますか？

今年，就活というものを行って，いわゆるIT企業というものを色々見て回ったけれど，大きい企業になるとどこもかしこも「ウチではプログラミングはしない」と言っていた．このSE(システムエンジニア)/PG(プログラマ)分業制というのは私が産まれてくるより前から存在する日本の悪習の一つと言われていたりするのだが，まだしばらくは続きそうだ．私は偶然にもプログラミングをする職場に内定をいただいたわけだが，それでもゼミの同期とかが「来年からSEだからプログラミングしないし余裕っしょ」とか言ってるのを聞くとツッコミたい気持ちが抑えられない．

私には夢がある．「SE職を駆逐する」ことだ．後には塵一つ残さない．

そのためにも，皆さんには強いプログラマを目指してほしい．美しいソースコードを書くことはその第一歩だ．

## 読みやすいソースコードとは

リーダブルコードが随所で叫ばれる昨今，読みやすいソースコードを書けることがプログラマーの条件みたいな風潮をあちこちで感じる．実際，読みやすいコードを書くことは大事だし，半年後の自分が読めるコードを目指すというのは真理だと思う．

ただ，リーダブルコード(オーム社)を読んで学んだことを，部分的に実行した結果ビミョーに読みにくいソースコードを作る人をたまに見かける．私も暗記したわけではないので厳しくは言えないが，その人にはおそらく自分のプログラムに対するこだわり，いわゆる__コーディング美学__が不足しているのではなかろうか．たとえリーダブルコード(オーム社)の内容に反していたって構わない．それが読みやすいという根拠さえあれば，割と普通に読めるものなので，ソースコードを書くときは「どうしてこれで可読性が上がるのか」を考えながら書いてほしい．少なくとも，後でそのコードについて質問されたとき，人のやり方を真似したけどどうしてそう書いたのか思い出せないとかいうのは勘弁だ．

~~というかリーダブルコード(オーム社)において，本質的な部分がだいたい章末や文章中にあっさり書いてあるだけなのが悪い~~

## ソースコード五ヵ条
ここでは，私が普段ソースコードを書くときに特に気を付けている5つのルールを紹介したい．これはきっと読みやすいコードを書くための一部であって全部ではないけれど，残りは皆さんがこれからいっぱいコードを書いていくうちに発見できると思っている．

### 第0条
#### コーディング規約は守ろう
本質とはズレるけど，念のため．たとえそれがあなたにとってアンリーダブルなものだとしても，無断で規約を破ることは許されないだろう．あなたの書いたメソッドは読みやすくなるかもしれないが，全体で見たら仕様がごちゃまぜになっているようにしか見えない．書き方を変えるなら規約も他のコードもすべて変更すべきだ．

### 第1条
#### メソッド内のインデント（ネスト）は4段階まで
言ったそばから否定するようで悪いが，正確には「__基本的に3段階で例外的に4段階も認める__」が正しい．二重for文の中のif文の中身なんかは他のメソッドにまとめたほうがオブジェクト指向っぽくなる．例外になるのは，if文の条件式が長すぎて分割したほうが読みやすくなるときだ．こういうのは設計から見直して積極的にreturnやcontinueを使うべきなのだが，たまに適用できないパターンがあって，そういうときは仕方なくインデントを利用している．

### 第2条
#### メソッドを作るときはインプットとアウトプットを明確に
基本中の基本である．Javaを使う人なら，javadocで要求されてるのだから書かない人はほぼいないだろう．仮にJavaでなかったとしても，

```
/*
*マウスとオブジェクトとの衝突を判定するメソッド
**input
*_mouseX,_mouseY:マウスカーソルの座標
*_object:衝突を判定する対象
**output：
*マウスカーソルがオブジェクト内ならtrue
*オブジェクト外ならfalse
*オブジェクトが存在しなかったらfalse
*/
```
とか書いておけば，後で機能を追加しようとしたときに使いやすくなるはずだ．なお，これもだいぶ個人差があるので，コーディング規約や自分の感覚に従ってほしい．

### 第3条
#### ソースコードのコメントアウトは使わない
皆さんはプログラミングしていて，アルゴリズムを途中でまるっと変えたくなったというのを一度は経験したことがあるのではないだろうか．そのとき，とりあえず手っ取り早い手段として，複数文コメントアウトでソースコードを退避させる人がいるが，あれ，あまり良くないと思う．コピペしたり色々するときに面倒なことが多い．

一番良いのはGitでバージョン管理して書き換えていくことだけど，導入するのも時間的コストが高いので，とりあえずGit環境がない人は，コメントアウトする部分を一つのメソッドとして移すのがオススメ．そうして移したメソッドAを見ながら，新しくメソッドBを書いて，メイン関数からメソッドBを呼び出せば後で見たときに理解しやすい．コメントアウト予定だったメソッドAは，頭にコメントでDeprecated（非推奨）と書いて残しておけば同じ失敗をしなくて済む．

### 第4条
#### 処理が明確な行にコメントは書かない
これはたぶん色んなところで言われているけど，実際のところ個人差があると思う．私は結構コメントを書く方で，人によってはアンリーダブルかもしれないって思うこともある．で，私が思う最低限これは書いておいたほうがいいんじゃないかっていうのは以下の2パターン
- ["言語名" and "関数名"]でGoogle検索したときに，日本語の解説ページが出てこないとき
- 飛び道具のような使い方をするとき

前者は書いた通りで，検索して英語の解説しかヒットしない関数なんてのは初見で理解できない可能性が高い．その理解するまでの時間も勿体ないので，コメントでどんな関数なのか書いておくべきだ．

後者は具体例を示すと分かりやすいかもしれない．例えば，こんなソースコードがあったとする．

```
void SortMinNumber(Arraylist list){
    list.size();
        .
        .
        .
}
```
このlist.size()が何をしているのか，初見ではまずわからないだろう．こういうのはコメントするに値する．普段のノリでコメントをつけると，以下のようになる．

```
list.size();    //nullチェック(force NPE)
```
そう，今回のsize()メソッドはlistの中身が空だったときに，nullを返しているのだ．force NPEというのは，海外の人たちがこの関数を利用するときの定型文らしい．NullPointerException(NPE)を強制的(force)に返しますよ，ということだろうか．話は脱線するが，だいたいのプログラミング言語において，size()メソッドの計算量はO(1)である．つまり，nullチェックするにあたりsize()は最速であるということだ．覚えておくといつか使えるかもしれない．

これが最低限必要なコメントで，私はさらに例外になる事例とか，for文のループ回数とか書いていたりする．それこそ，半年後の自分が必要になりそうなことを書いておけば大丈夫だろう．

言うまでもないことかもしれないが，自分で作った変数や関数を呼び出すときにコメントをつけるのは絶対にやめよう．それはさすがにネーミングセンスが悪い．せっかく自分で定義したんだから一目でわかる名前をつけるべき．検索したら色々ヒットするから参考にするといいと思う．

以前，どこかでコメント機能をGitに任せればソースコードがスッキリするという話を聞いたときは，天才かと思った．みんなもGit，始めよう！

### 第5条
#### 一つの関数やメソッドは画面にすべて映るようにする
ここまで長かったが，ようやく最後だ．ぶっちゃけた話，__これだけ覚えてもらえれば後の4つは忘れても構わない__．これを達成しようとすると前の4つを守る必要があるので書いたというのが正直なところだ．

なぜこれが重要なのかというと，単純に読むのが楽だからという一言に尽きる．プログラミングを家具の組み立てに置き換えて考えてみてほしい，設計図が両面に渡って書かれていて，1つ工程が進むたびにいちいち表と裏を行ったり来たりしたら面倒だしイライラするでしょ？あれと同じように，画面スクロールの手間は省くべきであると私は強く主張したい．長くなりすぎたらさらに小さくできないか検討しよう．

例えばProcessingなら30行くらいだろうか．それでもちょっと長い気もするが，これを超えてこなければかなり可読性は高いと思う．メイン関数だとかswitchで場合分けするときはさすがに無理でも，それ以外のときはなるべく画面に収まるようにしよう．

### 番外編
#### 外部入力は最小限にする
別にこれが読みやすさに影響するわけではないが，センサ等の外部入力装置を多く利用してきた私の心の叫びだと思って聞いてほしい．

これまであらゆるソースコードを書いてきたけど，理解不能なバグの9割はIOアクセスによるものだった．もしも，今後たとえばcsvファイルを読み込んだりするときは，一番最初にすべてメモリに置いておくなど，IOアクセスを最小限にする工夫を施したほうがいい．下手したら外部デバイスが壊れる．USBなんて読み書き回数に限度があるから特に注意だ．

## さいごに
ここまで読んでくれてありがとう．最後にこれも覚えていってほしい．

__これは私のコーディング美学であって，あなたにはあなたの美学がある．__

プログラミングを道具と割り切らないでくれ．そこにこだわりを見出してくれ．プログラミングは武器になる．その武器を磨いて，あなたの腕も磨いて，この世のSEというハンパな存在を駆逐しよう．

話はちょっと変わりますが，私は就職先の最終面接で「システムにバグがあったとき，あなたならどうするか」と聞かれました．ちょっと捻りが加えられてありますが，これもプログラミングのこだわりについて聞きたかったんだと思います．何が正解かは誰にもわかりませんが，この質問に自信をもって自分の意見を言えたらカッコイイですね．