「リーダブルコード」を読んだ
「リーダブルコード」を読んだので、各章について所感を書いていきます。節は特に参考になったところにのみ触れています。この本はニートになった直後くらいに有名な本だから買っとくかと買ってみたものの、結局積読になっていた本です。このブログを始めるにあたって最初の記事は何が良いだろうかと考えた時にこの本に目が留まり、この本なら記事にしやすいかなと思ったのが読み始めた動機です。
第1章「理解しやすいコード」
第1章はこの本の導入です。
1.2「読みやすさの基本定理」
「コードは他の人が短時間で理解できるように書かなければいけない。」「他の人というのは、自分のコードに見覚えのない6か月後の君自身かもしれない」とある。身に覚えがありすぎるので、過去の自分が書いたコードが短時間で理解出来るように改善していきたいです。
第2章「名前に情報を詰め込む」
変数・関数・クラス等の名前の決め方について解説されている章です。
2.1「明確な単語を選ぶ」
GetPageという名前の関数について、getではページをどこから取ってくるのか分からないから、インターネットから取ってくるならfetchやdownloadにした方が明確だとあり、これは納得。
2.2「tmpやretvalなどの汎用的な名前は避ける」
この節で参考になったのはループイテレータの項。ループのネストではインデックスでi, j, kを使いがちになりますが(他人のコードでも目にする事があるのでダメだとは思わないが)、members_iやusers_iのような説明的な名前をつけるとバグが目立ちやすくなるというのは納得。勿論やり過ぎはダメだと思いますが。節題にあるtmpやretvalに関しては、コードを改善する話でよく言われることなので新鮮味はありませんでした。
2.4「名前に情報を追加する」
値の単位を付けることや、バグになりそうな部分には形式等の属性を付けるというのは納得。自分はこういう所の命名が気分次第だったので改善していきたいです。
第3章「誤解されない名前」
他の意味に間違えられないような名前の決め方について解説されている章です。
3.3「限界値を含めるときはminとmaxを使う」
限界値を明確にするにはlimitのような曖昧な表現ではなくminやmaxのような表現にすると良いとのこと。
3.4「範囲を指定するときはfirstとlastを使う」
包含的な範囲についての話だが、意味的に正しく聞こえる場合はfirstとlast以外にminやmaxも使えるとのこと。
3.5「包含/排他的範囲にはbeginとendを使う」
endは包含にも取れてしまう曖昧な表現みたいだが、beginとendの対はイディオムになっているため包含/排他的範囲にはbeginとendが最善とのこと。
3.6「ブール値の名前」
ブール値は頭にis, has, can, shouldなどの単語を付けると分かりやすいということや、肯定形のほうが声に出して読みやすく短くて済むため否定形は避けたほうがいいというのは参考になる。自分の過去のコードを読んでいるとtrue/falseどっちの場合の処理かすぐに理解出来ない事がたまにあるので、ブール値の名前には気をつけたいです。
第4章「美しさ」
余白・配置・順序を整えて「目に優しい」コードにすることについて解説されている章です。
改行位置や並び、縦の線をまっすぐにする、ブロックにまとめるといったことが書かれています。個人的には、この章で解説されていることに関しては自動整形が使える場合はあまり意識しなくても良いかなという感じです。自動整形していない状態でもある程度整ったコードにしたい人や、自動整形を全く使わないという人には良い章だと思います。
第5章「コメントすべきことを知る」
「コメントの目的は、書き手の意図を読み手に知らせることである」という考えをもとに、コメントすべきことが解説されている章です。私はコメントを書くのが苦手だという事を自覚しているので、この章と次の第6章は非常に参考になりました。
5.2「自分の考えを記録する」
映画のDVDのように監督コメンタリーを入れるということや、コードの欠陥にコメントをつけるということ、定数にその値を入れた背景をコメントにするということが解説されています。
5.4「ライターズブロックを乗り越える」
自分の考えていることをとりあえず書き出してみようということが書いてある節です。私はコメントを書く際に手が止まってしまう事があるのですが、この節を読んで、コメントってもっと気楽に書いて良いんだと思えるようになりました。
第6章「コメントは正確で簡潔に」
「コメントは領域に対する情報の比率が高くなければいけない」という考えのもと、コメントを洗練することについて解説されている章です。
6.5「入出力のコーナーケースに実例を使う」
これは時折やっていたことではあるのですが、それでも自分の書いた古いコードは読み直したり実行してみたりして入出力を確認し直すことがあるので、今後は意識してやってきたいです。
第7章「制御フローを読みやすくする」
条件やループなどの制御フローを読みやすくすることについて解説されている章です。
7.1「条件式の引数の並び順」
左側に変化する調査対象の式を、右側にはあまり変化しない比較対象の式を、というのは今までほとんど意識していなかったことですが、確かにこう書くようにしておけば読みやすくなるなと納得。
7.2「if/elseブロックの並び順」
条件式は否定形より肯定形を使う、単純な条件を先に書く、関心を引く条件や目立つ条件を先に書く、といったことが解説されています。これも今までほとんど意識していなかったので、今後は意識していきたいです。
第8章「巨大な式を分割する」
巨大な式を飲み込みやすい大きさに分割することについて解説されている章です。
ド・モルガンの法則を使ってみるとか、とにかくいつもと反対のことをやってみるというのは頭の片隅にでも置いておくべき良いアドバイスだと思いました。自分にとってはこの章の悪いコード例の方はわざと冗長だったり分かりにくく書いた物に見えて仕方なかったのですが、同時にこの章の内容はプログラミングを学び始めてすぐの頃に知りたかったとも思わされました。巨大な式の分割方法がとても良く言語化されています。
第9章「変数と読みやすさ」
以下の3つの問題への対処について書かれている章です。
- 変数が多いと変数を追跡するのが難しくなる。
- 変数のスコープが大きいとスコープを把握する時間が長くなる。
- 変数が頻繁に変更されると現在の値を把握するのが難しくなる。
9.1「変数を削除する」
不要な変数として「役に立たない一時変数」「中間結果」「制御フロー変数」の3つが挙げられています。「役に立たない一時変数」が出てくる理由として「コードを編集した残骸。最初は複数の場所で使用されていた。あるいは何度も使おうと思っていたが一度しか使う機会が無かった」というようなことが書いてあり、これは自分的にはあるあるだなあと。コードを編集する時は使用する変数の整理も心がけようと思います。
第10章「無関係の下位問題を抽出する」
関数やコードブロックを見て「高レベルの目標に直接的な効果があるコード」と「無関係の下位問題を解決しているコード」を判別し、後者を抽出して別の関数にするということが解説されている章です。
実際にコードを書いているとたびたびこのような作業を行う事になるのは自分のようなニートでも分かっていることではありますが、その作業を言語化してくれるのはありがたいですね。8章と同様、この章の内容はプログラミングを学び始めてすぐの頃に知りたかったと思わされました。
第11章「一度に1つのことを」
一度に複数のこと(タスク)を行うコードは理解しにくいため、タスクを分離し一度に1つのタスクを行うようにコードを再構成するということが解説されている章です。10章よりも踏み込んでタスクという単位で見ていく章になっています。「一度に1つのタスクを行う」という技法が簡潔かつ的確に解説されています。
第12章「コードに思いを込める」
コードの動作を簡単な言葉で説明出来るようにして、その説明に合わせてコードを書く事でコードが洗練されるということが解説されている章です。要はラバーダッキング的な技法をコードと動作の説明を例にして解説しているということです。(章の最後のまとめ部分でラバーダッキングの名前が出ています。)
ラバーダッキング自体はとても有名なテクニックですが、この本では簡単な物ではありますがコードと説明を例に出して解説されているため、単に「ラバーダックに話しかける事で問題解決を図る」としか説明していない本やサイトよりかは説得力があるような気がします。
第13章「短いコードを書く」
コード量を削減する考え方について解説されている章です。
要求や当初の想定よりも短いコード量で済む解決策が存在するかもしれないということや、未使用のコードは削除するということ、ライブラリを活用するということ等が書かれています。
13.4「身近なライブラリに親しむ」
この節では、ライブラリの機能を活用するために「たまには標準ライブラリのすべての関数・モジュール・型の名前を15分かけて読んでみよう」と書かれています。これはやれば確かに効果があるだろうと思います。実行に移すのはちょっと億劫ですが…。
第14章「テストと読みやすさ」
テストを読みやすくて保守しやすいものにするための技法が解説されている章です。
自分自身テストをほとんど書いたことが無いので、書く機会が来ればこの章の内容を原則だと思って挑む事にしたいです。
第15章「分/時間カウンタ」を設計・実装する
Webサーバの直近1分間と直近1時間の転送バイト数を把握するために「分/時間カウンタ」を設計・実装するという演習的な章です。著者がどのような思考プロセスで問題を解決していくのかや、著者が同僚に質問していたように外部の視点を得ること等はとても参考になりました。
ただ、この章に関してはC++以外のコードでは解説されていないため、私にとってはややとっつきにくく、噛み砕くのに時間が掛かりました。他の言語の例を出すと章として冗長になってしまうという判断なのかもしれませんが、私自身C++を学んだ事が無いのでコード以外の解説内容を加味して「多分こういうことをやっているコードなのだろう」と推測するしかありませんでした。他の章でもC++のコードが出てくる部分では似たようなことを考えなかったわけではありませんが、15章は全体としてC++のコードしか扱っていないのでそれが顕著でした。章の内容自体はとても面白いです。この本の読者の中でも、私のようにC++を知らない人は15章については私と同じような感想を持つかもしれません。
C++以外での実装例
他の言語での実装例を調べた所、以下でPythonでの実装が紹介されていました。
中国語の記事ですが、手っ取り早くページに翻訳をかけて読みました。私としては、これを読んでようやく15章の内容に関してスッキリ出来たという感じです。
QiitaにGoでの実装を紹介している記事もあったので、Goを読める人はそちらも確認してみると良いかもしれません。
最後に
この本の最後には株式会社クリアコードの代表取締役の須藤功平氏による解説が収録されています。この本の内容を身につけて自然に読みやすいコードを書けるようになるための3つのステップが紹介されています。当たり前ですが、何よりもまず実際にやることが大事との事。この本に固執しすぎるのもダメだとは思いますが、個人的に納得のいく部分も多かったので、そういう部分はこれから書くコードに落とし込んで行きたいと思います。
ディスカッション
コメント一覧
まだ、コメントがありません