web学習日記

プログラミングやweb関係を学んだことを呟くブログ

リーダブルコードを読んだのでまとめ

f:id:nana205:20190709193928j:plain

第1章 理解しやすいコード

コードを書く原則 コードは理解しやすくしなければならない コードは他の人が短時間で理解できるように書かなければいけない

第2章 名前に情報を詰め込む

.明快な単語を選ぶ 例えばGetではなく、状況に応じて、DownloadやFetchなど .汎用的な名前を避ける(あるいは使う状況を選ぶ) tempやretvalなどより、目的や値を表すものであるべき。ただし、スコープにもよる。 .抽象的な名前よりも具体的な名前を使う ServerCanStart()では抽象的具体的にはCanListenOnPort()の方がいい .接尾辞や接頭辞を使って情報を追加する ミリ秒を表す変数に、_msを追加する、など。 .名前の長さを決める

.名前のフォーマットで情報を伝える クラスのメンバ変数にアンダースコアをつけるなど

明快な単語を選ぶ 例 Def GetPage(url);

Def DownloadPage();

変数や関数の構成要素の名前は抽象的でなはく具体的に

第3章 誤解されない名前

名前が他の意味と間違われないだろうか常に問う 限界値、包含的または排他的範囲などを意識した名前にする。 妙なプライドは捨て、ユーザーの期待に合わせる事を心がける 複数の名前を検討する。 > template/ reuse / copy / inherit、どれが良いだろうか

第4章 美しさ

3つの原則  一貫性のあるレイアウト  似ているコードは似ているようにみせる  空行を使い大きなブロックを段落に分ける

第5章 コメントするべきでないこと

コードからすぐにわかることはコメントに書かない 自分の考えを記録する ライターズブロックを乗り越える プログラマの多くはコメントを書きたがらない。コメントをうまく書くのは大変だと思っているからだ。 コメントを書くjことによって品質が次第によくなっていくことを理解する。 コメントのためのコメントをしない コードの欠陥にコメントをつける 読み手の立場になって考える

第6章コメントは正確に簡潔に

コメントは領域に対する情報の比率が高くなければいけない コメントを簡潔にしておく 曖昧な代名詞を避ける コードの意図を書く 情報密度の高い言葉を使う

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

条件式の引数の並び順 if(length>=10) or if(10<=length) if/elseブロックの並び順 .条件式は否定形よりも肯定形を使う。 .単純な条件式を先に書く。ifとelseが同じ画面に表示されるので見やすい。 .関心を引く条件や目立つ条件を先に書く。 do/whileループを避ける .do/whileはif文、while文、for文などの条件と違い「下から上」に読まなければならないので不自然 関数から早く返す return を早く返してあげることで読みやすくなることがある 行を短くするより他人が李愛するのにかかる時間を短くする ネストを浅くする

第8章 巨大な式を分割する

巨大な式は飲み込みやすい大きさに分割する 説明変数 .式を簡単に分割するには説明変数を用いてもいい .ド・モルガンの法則を使う 「notを分配してand/orを反転する」「notをくくりだす」 短絡評価の悪用 .プール演算子は短絡評価を行うものが多いので注意 .頭がいい」コードに気をつける。あとで他人がコードを読むときに分かりにくくなる

より優雅な手法を見つける 複雑なコードは「もっと簡単なコードがあるはずだ」と考える

巨大な文を分割する .巨大な文は理解するのが難しくなってしまうため分割することを検討する

第9章 変数と読みやすさ

①変数が多いと変数を追跡するのが難しくなる ②変数のスコープが大きいとスコープを把握するのに時間がかかる ③変数が頻繁に変更されると現在の値を把握するのが難しくなる

変数を削除する  コードが読みやすくならない変数を削除する 役立たない一時変数

中間結果を削除する 制御フローを変数を削除する

グローバル変数は避ける グローバル変数はどこでどのように使われているのか追跡するのが難しい また「名前空間を汚染する」(ローカル変数と衝突する恐れがあること)から避けたほうが良い。 変数のことが見えるコード行数をできるだけ減らす

変数は一度だけ扱う  変数を操作する場所が多くなると、現在地の判断が難しくなるから

まとめ ・邪魔な変数を削除する ・変数のスコープを小さくする ・一度だけ書き込む変数をつかう

第10章 コードの再構成

①プログラムと主目的と関係のない「無関係の下位問題」を抽出する ②コードを再構成して、一度に一つのことをやるようにする ③最初にコードを言葉で説明する。その説明を元にキレイな解決策を作る ④コードを完全に削除できる状況について説明する。また、コードを書かずに済ませる状況についても説明する(コードを理解しやすくするにはコードを書かないのが一番)

エンジニアリングとは、大きな問題を小さな問題に分割して、それぞれの解決策を組み立てることに他ならない。この原則をコードに当てはめれば、堅ろうで読みやいコードになる

無関係に下位問題を積極的に見つけて抽出すること

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

汎用コードをたくさん作る 凡庸コードはプロジェクトから切り離して考えられるので扱いやすい

このプログラミングはトップダウンボトムアップトップダウンプログラミングとは、先に高レベルのモジュール関数を設計してから、それらをサポートする低レベルの関数を実装していく方式だ。 ボトムアップとはプログラミングとは、先にすべての下位問題を解決してから、それらを利用する高レベルのコンポーネントを実装していく方式だ。

プロジェクトに特化した機能 抽出する下位問題というのは、プロジェクトから完全に独立したものであるほうがいい。ただし、完全に独立していなくても、それは問題ない。下位問題をのぞくだけでも効果がある。

既存のインターフェースを簡潔にする 「理想とは程遠いインターフェースに妥協することはない」 自分でラッパー関数を用意して汚いインターフェースを覆い隠すのも綺麗なコードをつくるための手法

やりすぎ 小さな関数を作りすぎても逆に見にくくなってしまう。 「無関係の下位問題を積極的に見つけ抽出する」ことは目的だが、やりすぎて見にくくなってしまうのには注意が必要

まとめ プロジェクト固有のコードから汎用コードを分離するということ。 ほとんどのコードは汎用化できる。

第11章

一度に一つのことを

一度に一つのことをするコードは理解しにくい。例えば、オブジェクトを生成して、データを綺麗にして、入力をパースして、ビジネスロジックを適用しているようなコードだ。 これらのコードがすべて絡みあっていると、「タスク」が完全に個別に完結しているコードよりも理解するのが難しい。 コードは一つずつタスクを行うようにしなければならない

一度に一つのタスクをする ①コードが行っている「タスク」をすべて列挙する。この「タスク」 という言葉はユルく使っている。「オブジェクトが妥当かどうかを確認する」のように小さなこともあれば、「ツリーのすべてのノードをイテレートする」のようにあいまいなこともある。 ②タスクをできるだけ異なる関数に分割する。少なくとも異なる領域に分割する。

オブジェクトから値を抽出する 「一度に一つのタスク」を適用する まとめ 「一度にひとつのタスク」を行う 読みにくいコードがあれば、そこで行われているタスクをすべて列挙する。そこには別の関数(やクラス)に分割できるタスクがあるだろう。 それ以外は関数の論理的な「段落」になる。 タスクをどのように分割するかよりも、分割するということが大切。

第12章 コードに想いを込める

おばあちゃんがわかるように説明できなければ、本当に理解したとは言えない アルバート・アインシュタイン

誰かに複雑な考えを伝えるときには、細かいことまで話すぎると相手を混乱させてしまう。自分よりも知識が少ない人が理解できるような「簡単な言葉」で説明する能力が必要だ。自分の考えを凝縮して、最も大切な概念にすることが必要になる。これは誰かに理解してもらうだけでなく、自分の考えをより明確にすることにもなる。 コードもこれと同様で読み手が理解できるように「簡単な言葉で」書くべきなのだ

①コードの動作を簡単な言葉で同僚にも分かるように説明する。 ②その説明の中で使っているキーワードやフレーズに注目する ③その説明に合わせてコードをかく

ロジックを簡単に説明する

短いコードを書く プログラマが学ぶべき大切な技法というのは、コードを書かないときを知ることなのかもしれない。自分で書いたコードであれば、すべての行をテストして保守しなければならない。 ライブラリの再利用や機能を削除することで、時間を節約したり、コードを簡潔に維持したりできる。 最も読みやすいコードは何も書かれていないコードだ!

その機能の実装について悩まないで、きっと必要ないから プロジェクトを開始するときには、これから実装するかっこいい機能のことを考えて興奮するものだ。そして、プロジェクトに欠かせない機能を過剰に見積もってしまう。その結果、多くの機能が、完結しないか、全く使われていないか、アプリケーションを複雑にするものになってしまう。 プログラマというのは、実装にかかる労力を過小評価するものでもある。プロトタイプの実装にかかる時間を楽観的に見積もったり、将来的には必要となる保守や文章化などの「負担」時間を忘れがちになる。

質問と要求の分割 すべてのプログラムが、高速で、100%正しくて、あらゆる入力をうまく処理する必要はない。要求を詳しく調べれば、問題をもっと簡単にできることもある。そうすれば、必要なコードも短くて済む。

キャッシュを追加する

コードを小さく保つ ソフトウェアプロジェクトを始めるときには、ソースファイルは一つや二つしかない。しかし、プロジェクトが進んでいくと、ファイルが増えていく。ディレクトリを分けてファイルを整理しなければならなくなっていく。どの関数がどの関数を呼び出しているのか分からなくなってくる。バグを見つけるのもだんだん面倒になってくる。 最終的には、いろんなディレクトリにファイルが散らばることになる。プロジェクトは巨大になって、すべてを把握できる人もいなくなる、新しい機能を追加するのが苦痛になってくる。コードを扱うのが厄介になり楽しくなくなる。 あらゆる協調システムは成長する。それらを結びつける複雑さはもっと速い速度で成長する。 つまり、プロジェクトが成長しても、コードをできるだけ小さく軽量に維持するしかない。 そのためにやること ①凡庸的な「ユーティリティ」コードを作って、重複コードを削除する。 ②未使用のコードや無用の機能を削除する ③プロジェクトをサブプロジェクトに分割する ④コードの重量を意識する。軽量で機敏にしておく。

身近なライブラリに親しむ 「ライブラリを熟知して、実際に活用することが大切」 たまには標準ライブラリの全ての関数・モジュール・型の名前を15分かけて読んでみよう! 標準ライブラリとはAPIや組み込みモジュールのことだ。

ライブラリの再利用はなぜいいことなのか 統計ではあるが、平均的なソフトウェアエンジニアが一日に書く出荷用のコードは10行なのだそうだ。 嘘だと思えるが、大切なのは"出荷用"という言葉だ。成熟したライブラリコードの裏側には、膨大な設計・デバッグ・修正・文書・最適化・テスト・が存在する。このダーウィンの進化を生き延びてきたコードには価値があるからだ。

まとめ ・不必要な機能をプロダクトから削除する。過剰な機能はもたせない。 ・最も簡単に問題を解決できるような要求を与える。 ・定期的にすべてのAPIを読んで、標準ライブラリに慣れ親しんでおく