なぜ私はコードを書く/読むのが遅いのか

今年Webエンジニア2年目になります。
さて、タイトルの通りですが、自分は普段から仕事でコードを書く/読むのが遅いな、と感じることが多くあります。例えば、シニアエンジニアが工数の見積もりをしてきた時に、その工数をみて「いや、私この工数では終わらないが？」と思ったり、PMに「この修正は何日で終わりますか？」と聞かれて答えた後に実際に取り掛かったら自分の読みが甘くて倍かかってしまった、とか。

最近話題の「プログラマー脳」にも絡めて、なぜ自分がコードを書くのが遅いと感じたか、どうしたら少しは改善したか？について説明してきたいと思います。

### なぜコードを「読む」のが遅いのか？
#### 1. 上から下に読んでいる間に、コードが一定数より長いと上の処理内容を忘れる
これは「プログラマー脳」でも言われている通り、コードリーディングで使われるのは短期脳ですが、プログラムが短い時は問題ないものの、長いプログラムを読んでいると、短期脳のスペックを上回るために単純に忘れてしまいます。

#### 2. 一行一行は読めているんだけど、全体像が分からなくて理解した気がしない
そのままなの意味ですが、一行一行がやっていることは分かるんだけど、1の通り忘れるのと、全体像が把握出来ないため、結局何がしたいプログラムだったのか、全部読んでも分からない...ということがよく発生します。

#### どうすれば良いか？
##### a. コードに項番と処理内容のコメントを追加する
処理内容を簡潔にまとめながら読めば、何やってたっけ？と忘れた際にそのコメントさえ読めば、内容を把握するのが楽になります。

##### b. フロー図を描く
これは時間がないとなかなか出来ない&ほぼ設計書になってしまうので、面倒ではありますが自分はこの方法でないと、なかなか全体像を把握できないので、よく簡単なフロー図をGoogle Spreadsheetとかにまとめてメモしています。

##### c. (言語特有の文法やライブラリを記憶する)
これは「プログラマー脳」で言われていたことです。ただ、自分がコードを読むのが遅いのは、単に文法やライブラリを知らないから、ではないと思っています。
主にプログラムの全体像をコードを読むだけではなかなか把握しきれないために、脳がパンクまたは忘れてしまって、理解できない/遅い状態が発生するのだと思っています。なので、主な解消方法は上記2つかなというところです。

#### なぜコードを「書く」のが遅いのか？
##### 1. 何をするのかきちんと把握していない
○○の機能を開発して、修正して、と言われたけど、具体的に今あるコードのどこの部分をどう修正したら良いのか分かっていない、や、設計が曖昧なのにいきなり実装に入ってしまうなどです。

##### 2. コードの流れを把握していないため、思わぬところで例外やエラーが発生して時間を食う
デバックしたり、printしてる間に時間がなくなっていくパターン。

##### 3. 何をテストすべきか分かっていない/テストに慣れていない
実装は出来たけど、何をテストすれば良いんだっけ？と実装してから悩むパターン。
また、テストに慣れていないせいで、テストは書いたけど予想外のところでエラーが発生したり、テストが通らなくて頭を抱えてしまう。

#### どうすれば良いか？
##### a. 設計をきちんとやってから実装に入る
まずこれに尽きると思います。逆に言えばちゃんと設計していれば、ちゃんと何を修正するのか分かっていれば、そもそもコードを書くスピード=タイピングの速さ、でしかないはずなんです。
なのに時間がかかるということは、書きながらこれで良いんだっけ？と考えてしまったり、書いた後で、いやこれはちょっと違うな、とか修正してしまったりしてしまうことなので、設計さえしておけば時間はかからないはずです。

##### b. テストについて学ぶ
これはテスト駆動開発について学べば解消するはずです（まだあまり実践できていない）
ただ、実務を始めたばかりの頃の自分は、コードを書いた後で、で何をテストすれば良いんだっけ？と考えてしまい、さらにはテストが上手く書けなくて/通らなくて、時間がかかってしまっていました。
ただ、今は何をテストすべきか、の理解が深まったのと、単純にテストをいくつも書いてテストの書き方のお作法を学んだため、無作為にいろいろ試してテストを無理矢理通そうとする、といったことは減りました。

##### c. 文法を覚える
これも「プログラマー脳」で言われていたことです。
私も結構Javaの文法をド忘れします。(配列の初期化と値のアサインって、同時にやるにはどう書けば良いんだっけ？とか)
その度にググればいっか、と思っていたのですが、大体その時点で記憶しよう、と思ってググっているわけではないので、またすぐ忘れてしまいます。さらには、ググろうと思ってタブを開いてググろうとすると、集中力も切れるし、たまに検索結果に出てきた別のことに気を取られてしまいます。
小さいことではありますが、こうした無駄な作業をなくすことで、時間ロスを減らすことが出来ます。

##### d. PRで指摘されるような細かいことを間違えない
これは一概に○○が悪い、というように言えないのですが、例えばmapを使えば良いところをfor文内で処理したり、変数名が分かりづらかったり、などなど。
これは言語によっても文法が異なるので、Javaでは出来ないけどKotlinならうまいこと書けることだったりするのかもしれませんが、これもその仕様を知っているか知らないかで違ってきます。

### 最後に
初心者がプログラミングがまあ一通りできるようになった後でつまづくポイントはここだと思います。
ここでは簡潔になぜ起きるのか、どうしたら改善できるのか、についてまとめましたが、正直ここまで来るのに半年以上かかりました（遅い）
いまだにめちゃくちゃコードを書くスピードがこれで上がったか、というとまだ改善途中ではあるのですが、これらの方法を何度も実践したり、またはこれから更に良い方法を見つけたら追記していきたいと思います。
ちなみに一応こうした問題について、英語でも色々ググったりしてみましたが、ぶっちゃけダイレクトな解決方法は見つかりませんでした。プログラマー脳で述べられているのも、結局文法を記憶したり、コードをプリントアウトして変数の流れや分岐を線で囲む、など割と方法論としてはちょっと違う、古い、と感じることも多かったため、めちゃくちゃ参考になる！とは感じませんでした。
ただ、特にコードを書く上で大事なのは設計になるということは実務をやっていて気がつきました。ここに書いている方法が何かしら誰かの助けになれば幸いです。
もしくは、もっと良い方法をご存知の方がいれば、ぜひコメントで教えていただきたいです！

### 参考
・[「プログラマー脳」](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC%E8%84%B3-%EF%BD%9E%E5%84%AA%E3%82%8C%E3%81%9F%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%E8%AA%8D%E7%9F%A5%E7%A7%91%E5%AD%A6%E3%81%AB%E5%9F%BA%E3%81%A5%E3%81%8F%E3%82%A2%E3%83%97%E3%83%AD%E3%83%BC%E3%83%81-Felienne-Hermans/dp/4798068535)Felienne Hermans著
・[「テスト駆動開発」](https://www.amazon.co.jp/%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA-Kent-Beck/dp/4274217884)Kent Beck著