はじめに
エンジニアになって一年、目の前のチケットの一機能を、使用している言語やフレームワークによってまずは動くものを実装し切る、ということをやってきた。
そして最近、動くだけでなく長く動かし続ける、運用しやすいサービスを作る為には、技術を使いこなすための「土台」となるエンジニアとしての一般教養みたいなものがもっと必要だなと感じていた。
そんな時評判の良さそうなこの本を見つけ、サブタイトルの 3年目までに身につけたい一生役立つ101の原理原則という文言にも惹かれて即購入。
良いコードを書くための前提、原理原則、思考法、視点が詰まった本だったので、要点や特に印象的だったことを備忘録として書いておく。
第1章 前提
コードは設計書である
-
「基本設計」から「詳細設計」「プログラミング」「テスト」まですべてが設計であり、そのアウトプットが設計書である「コード」。
-
コードには「How」や「What」はよく表現されているが、「Why」は無い。この設計理由をドキュメントに記述しておくと保守に役立つ。
コードは必ず変更される
-
コードは一度書いて終わりということはほぼなく、修正されるもの。
-
コードを書いているより、読むことの方が長く時間を使う。
読みやすいものを作るのが大切。
第2章 原則
KISS(Keep It Simple, Stupid)
-
コードを書く時、最優先の価値を「単純性」「簡潔性」におく。
-
シンプルを保つために、以下の気持ちを持ち込まないように注意する。
- 新しく覚えた技術を使いたい
- 将来の必要に備えたい
- 勝手に要件を加える
DRY(Don’t Repeat Yourself)
-
同じコードを重複して書かない。
-
一つの事実は一つの場所のみに存在させる。
-
テストを用意してから修正を行う。品質を守る。
YAGNI(You Are’nt Going to Need It)
-
「たぶん必要になるだろう」「必要になるかもしれない」でコードを書かない。
-
うまくいく方法のうち、最もシンプルな方法で行う。
PIE(Program Intently and Expressively)
-
コードは人が読むものであり、コンパイラが読むものでは無い。
-
「Why」つまりなぜそれをしているのかを表現するためにはコメントをうかう。
OPC(Open Closed Pronciple)
- コードは「拡張に対して開いている」「修正に対して閉じている」という二つを満たすように設計する。
- 修正に対して閉じているとは、コードの振る舞いを拡張しても、その他のコードはまったく影響を受けないということ。
名前重要
- 内容から名前を考えたら、今度は名前から推測できる内容を考える。一致すれば良い名前で、一致しなければ要注意。
第3章 思想
柔軟性
-
即効果のあるコード以外は、我慢して書かないようにする。
-
凝った設計からトップダウンで得られる柔軟性より、シンプルからスタートしてユニットテストからボトムアップ的に得られる柔軟性の方が効果的。
変更頻度
-
同じタイミングで変更される要素は同じところに置き、異なるタイミングで変更される要素は別の場所に分けておく。
-
データについては、例えば一つの関数実行中だけで使用されるデータであれば、それはその関数内のローカル変数にする。
アーキテクチャ根底技法
- よいコードには、以下のような型がある。
抽象、カプセル化、情報隠蔽、パッケージ化、関心の分離、ポリシーと実装の分離、インタフェースと実装の分離、参照の一点性、分割統治
抽象
-
複雑な対象に取り組むときは、余計なものを捨て、本質を捉えるようにする。その際、本質そのものを捉えることも大事だが、取り組んでいる問題について、「今着目している側面からの本質」として捉えることが大切。
-
異なる複数の対象に取り組むときは一般化する。共通する性質を見出し、共通点を組み合わせて汎用的な概念を構成する。
情報隠蔽
-
モジュールの利用者には、そのモジュールを利用するために必要なすべての情報を与え、それ以外の情報は一切見せないこと。
-
モジュールの作成者には、そのモジュールを実装するために必要なすべての情報を与え、それ以外の情報は一切見せないこと。
テスト容易性
-
テスト容易性のための設計では、モジュール間の依存関係の排除がポイント。
-
テストの品質が本体の品質。
単純原理
-
シンプルにこだわる。
-
複雑なところにバグは出る。
UNIX思想
-
小は美なり
小さいソフトウェアは美しい。小さいソフトウェアは扱いやすから。
- 理解が簡単
- 保守が容易
- マシンリソースが節約できる
-
即行プロトタイプ
- プロトタイプを早くに作成することで、前提の誤りを早期に発見できる。
- 要件不備による手戻りを減らせる。
-
データはテキスト
- テキストファイルは万能で、移植性が高く、人が見やすい。
- ツールやコマンドで処理することも容易である。
第4章 視点
結合度
-
モジュール間は「疎遠」にする。
-
結合が密だと、互いに影響を与えて再利用しにくくなる。
技術的負債
-
問題コードは「借金」である。
-
すぐに返済できるなら問題ないが、返済が長引くと利子が付いて返済不可になり、自己破産する。なるべく、早めに返済を行い、問題コードと上手く付き合う方法を知る。
第5章 習慣
プログラマの3大美徳
-
プログラマは「怠慢」「短気」「傲慢」であれ!
-
怠慢:労力を減らす手間を惜しまない
-
短気:効率的に作業してないことに怒りを感じること
-
傲慢:過剰な自尊心を持つことで、己を強く保つ努力をする
ボーイスカウトの原則
-
コードは掃除して帰る。前よりも少しきれいな状態にすることで、品質が保たれるようになる。
-
コードは改良してからコミット。完璧を目指さなくても良い。少しの改善をすることが重要。
パフォーマンスの箴言
-
「速い」より「よい」コードを作る。
-
速いコードは、「割に合わない」ことが多く、大切な何かを失う。速さは何かとのトレードオフで成り立つ。
第6章 手法
防御的プログラミング
- 「かもしれない」プログラミングを心がけ、不足の事態に備える。
ラバーダッキング
-
「説明する」というある種のデバッグ手法。
-
発生している問題や、問題を抱えているコードを「誰か」に説明する。すると問題の原因に自ら気付き、じ解決できるというもの。
-
人に話す前に、人形に対して説明してみる。
コンテキスト
-
コードを書く時、コンテキストを先に示すようにする。それにより、読み手はまず何についてのコードなのかを把握することができる。
-
コードを読むときには、コンテキストを組んでからその内側のコードを理解するようにする。
第7章 法則
ブルックスの法則
-
要員追加は火に油。
-
遅れを取り戻すための要員追加は、遅延の拡大になることが多い。
-
ユーザと調整して機能に優先度を付け、リリースを行う。
割れた窓の法則
-
悪いコードは蟻の一穴。ちょっとした綻びが、全体を崩壊させるものになる。
-
悪いコードがあると、人を適当に作業する心理にさせる。悪いコードの存在が、さらなる悪いコードを呼び、負の連鎖を誘発する。
セカンドシステム症候群
- 2回目のリリースは危険。なぜなら、慣れから来る自信が失敗を招きやすいから。
車輪の再発明
-
既にあるものを作ること。時間の無駄であることが多く、既にあるものの方が品質が優れていることが多い。
-
車輪以外、つまり本来やるべき作業に注力する。
ヤクの毛刈り
-
トラブルは芋づる式で、問題を解決しようとしたら別の問題が出てきて、最終的に何を解決したかったのか忘れることがある。そのような状況に陥った場合は、早々に切り上げる方が良い。
-
問題が起こったら、何が目的だったのか考える癖をつける。目的と違う・コストと見合わないと感じたら、作業をやめて別の道を模索する。
さいごに
これまで自分がコードを書いた経験から学んできたこと、先輩から教わったこと、何かでチラッと聞いたことがある内容がたくさんあり、完全な駆け出しではなく少し経験を積んだ今だからこそ腹落ちしてこの本を読むことができたと思う。
幅広い思考法を学んだので、たまにこの自分の備忘録記事も読み返して、自然とこの本で学んだ様々な視点を持って考えてプログラミングに取り組めるようになっていきたい。