※自社のナレッジに投稿した記事をこっそりQiitaにも。。。
リーダブルコードを読んだので、その内容をピックアップしてまとめます。
どんな本?
Dustin Boswell、Trevor Foucherによって書かれた、良いコードを書くための考え方とテクニックがまとめられた一冊です。良いコードとはどんなものかというと、この本での定義は
「読みやすく、理解しやすいコードである」
となります。この本の内容はとても基本的です。複雑なデザインパターンやアーキテクチャの話は一切出てきません。章ごとに多少は難易度の差はあれど、どの章も「コードを理解しやすくする」ための基本的な考え方とテクニックを紹介しています。
所謂"技術本"というと「文字がいっぱいでつらつらと書いてあって読めない。。。」だとか「内容が専門的で難しくてついていけない。。。」という経験があったり、そのようなイメージを持っていて敬遠している方もいらっしゃるかと思います。私もそのようなイメージを持っていた一人ではあったのですが、リーダブルコードはそれを覆してきました。とても読みやすく、理解しやすいです。専門的な知識もほとんど不要です。ページ数は200程度で、1ページ当たりの情報量もあまり多くないので、読み切るのはそれほど大変ではありません。
なにより、納得と新しい発見の連続を体感できます!理解しやすいコードを書くために必要なことは、すべてこの一冊の中に載っている、読み終えた後にはきっとこう実感できると思います。私にとって初めて買った技術本がこの本でよかったと心から思っています。そのくらい自信をもってお勧めできる本です。
本稿では、リーダブルコードの内容から、特に基礎的で、今日からでも実践を始められるような内容をいくつかピックアップして紹介します。文章が長くなってしまい、内容が中途半端になることを避けるため、すべての内容をさわりだけ紹介するということはここではしません。
この文章が、理解しやすいコードを書く意識のきっかけになればと願っています。
理解しやすいコード
リーダブルコードにて語られている「理解しやすいコード」とはどんなものなのでしょう?そして、なぜ「理解しやすいコード」を書く必要があるのでしょう?
リーダブルコードでは、理解しやすいコードについて、一つの原則を提示しています。
コードは他の人が最短時間で理解できるように書かなければいけない。
リーダブルコードで紹介されているテクニックは、すべてこの原則に帰結します。例えば同僚にソースを見せた時に、その同僚がソースに書かれている処理の内容を理解するまでの時間を最短にすることを目標とします。
**「理解する」**とは、なんとなく追えるという程度のことではありません。そのソースに変更を加えたり、バグを発見できる状態のことを指します。
理解しやすいコードを書く理由は、他の人があなたのソースコードを読むかもしれないからです。
同じプロジェクトのメンバー、あなたの仕事を引き継いだ人はもちろん、場合によっては社内中の人が使うような再利用可能コードを書くことになるかもしれないし、GitHubで公開されるようなコードを書けば世界中の人があなたのソースコードを読めることになります。
そして、「他の人」には、数か月後の**「自分自身」**も含まれます。
理解しやすいコードを書いていれば、保守においても改修においてもスムーズなスタートを切る理由となり、プログラマの意欲を削がず、高い生産性につながると思います。
実際、私自身も新しく入った案件のソースを初めて見た時に「これ読むの?うへぇ。。。」と、のっけからダメージを負った経験もあります。その経験があるからこそ、この原則に従う重要性を深く認識できたと思います。
また、「コードを書くときに考慮しなければいけない点はほかにもたくさんある!」と思う方もいらっしゃると思いますが、最優先すべき事項はこの「理解しやすいコード」であると断言します。
理解しやすいコードを書くことは、そのほかの考慮事項とは競合しません。どんなコードを書く時にも、**「このコードは理解しやすいかな?」**と一歩下がって自問自答することができます。
名前に情報を詰め込む
ここからは、「理解しやすいコード」を書くための具体的な手法をいくつか採り上げます。
まずは、プログラム、クラス、関数や変数などの命名についてです。命名についての最も重要な考え方は、その名前にできる限り情報を含めて伝えてあげるということです。
例えば「size」という名前の変数はよく見かけますが、これでは何のサイズを表す変数なのかは名前からは判断できません。これを例えば「queryResultSize」とすると、クエリの実行結果の件数が格納される変数だということが理解できるようになります。
「最短時間で理解できる」という原則を考えると、どちらのような命名をしなければならないかははっきりします。変数名に情報が足りなければ、それを初めて読むプログラマは、その意味を知るために1回り余分にソースを追わなければならないのです。
私は、名前に情報を詰め込むという心がけは、プログラムに限った話ではないなととらえています。ドキュメントのファイル名、メールの件名、質問や相談をするときの最初の一言など、様々な場面で通用する原則だと思います。私自身も、常に**「名は体を表す」**という言葉を脳の片隅において仕事をしています。
具体的な手法として**「明確な単語を選ぶ」、「接尾辞や接頭辞を使って情報を追加する」**などの手法が紹介されています。
「明確な単語を選ぶ」は、例えば「Get」ではなく、状況に応じて「Fetch」や「Download」を使うなど、より特定的な単語に置き換えることで、正確な理解を提供できるというものです。
「接尾辞や接頭辞を使って情報を追加する」は、例えばミリ秒を表す変数名には、後ろに「_ms」をつけるなど、変数に関する重要な条件などを変数名に追加するというものです。
**「名前は短いコメントだと思えばいい」**という考え方がこの章で提唱されています。より説明的(かつ、できれば長くなりすぎず)な命名ができれば、ソースの可読性は一気に向上していくと思います。
私は命名センスにはあまり自信がないので、この原則に従って訓練を積んでいこうと思います。
コメントすべきことを知る
続いてはコメントについてです。
この章の初めに、コメントを記載することの目的が提示されています。それは
**「書き手の意図を読み手に知らせること」**です。
コードを書いているときの、その人の頭の中にある重要な情報が失われないように書き留めておくのが重要です。リーダブルコードでは「監督のコメンタリー」という表現がされています。コードに対する大切な考えを記録したり、読み手の立場に立って疑問に思われそうなことにあらかじめ回答することを心がけます。
例えば以下のような、「なぜ」についてのコメントを書くといいです。
// 複数箇所で同じ条件で表示判定を行うため、事前にメンバ変数で表示フラグを保持しておく
var isVisible;
また、コードの欠陥についてコメントを入れることも重要です。コードに欠陥が生まれることは宿命であり、恥ずかしいものではありません。決して隠ぺいすることなく、起こりうる危険性が発覚したものに関してはコメントに残しておきます。
改善が必要なものには「TODO」、不具合があり修正の必要性があるコードには「FIXME」などのコメントを付与します。EclipseなどのIDEでは、このコメントを拾って一覧表示してくれるような機能があるので、ぜひ活用してみてください。
コメントを記載するうえで私が大切にしていることが、**「今コメントを書く」**ということです。言い方を変えると「後からまとめてコメントを入れようとしない」となります。書き手の意図を表現するためにコメントを記載するのに適したタイミングは、ソースコードを書いている今しかないと考えているからです。
脳は言語情報を驚くほど短い時間で忘れてしまいます。特に「ひらめいた!」となるようなアイデアはものの数分で脳内からいなくなってしまいます。その数分の間にソースコード自体は書けても、その意図を説明するコメントが書けていなければ、翌日にはそのソースコードから自分が置いていかれてしまうのです。よくできたアイデアだったはずが、なぜこう書かれているかわからない「腫れ物」のような扱いに。。。
そうならないためにも、「今コメントを書く」ことを意識しています。ソースコード+コメントがどちらも同じ状態の脳から書かれているからこそ、自分のアイデアが、質の高い成果物として後に残る結果になると考えています。
リーダブルコードで取り上げられている、コメントについてもう一つ重要なことは、コメントをするべきではないことを知ることです。
コメント自体は処理に影響をしませんし、あってもなくてもシステムに与える結果は同じなはずです。それでもコメントを書く理由は、コードの可読性を上げ、そのコードのより深い理解に一役買うからです。
コードの理解を助ける役割を持つコメントが、コードの可読性を下げることを助長してはいけないのです。(読み手のやる気を奪うことはもっとしてはいけないことです。。。)
そこで大事なことは、「価値のあるコメントを書く」ということです。もちろん「価値のないコメントを書かない」ということと表裏一体です。
これについての重要な考え方は**「コードからすぐにわかることをコメントに書かない」**ということです。
// 生徒の名前
private String studentName;
例えばこのようなコメントです。コードを読めばわかるし、何も新しい情報は提供していません。
// 受け取った顧客情報を顧客マスタテーブルにINSERTします
function createData($array)
この例は一見不足している情報を補う「価値あるコメント」に見えますが、良い例ではありません。この例で情報を補完するには、コメントを付与するより先に、情報の足りていない関数名と引数名を変更することが必要です。
(すでにこの関数名でサービスインしてしまっている、影響範囲が大きすぎてテストの工数が膨らむから直せない、といった事情がある場合には、仕方なくコメント付与により情報を追加する場合があるかもしれません。極力未然に防ぎたいものです。)
リーダブルコードには、この他にもコメントに関する様々なベストプラクティスが書かれています。
これらを踏まえて、「価値のあるコメント」をかけるようになることが、「価値のあるコード」をコンスタントに作成できる入口になると思っています。
無関係の下位問題を抽出する
最後に紹介するのは、コードの分解についてです。
コードの分解に関して、リーダブルコードで語られているのは、
「関数やコードブロックの高レベルの目標を自問して、それとは無関係の下位問題を解決している部分のコードを抽出して別の関数にする」
という手法です。
この手法を使いこなすことができれば、コードの読みやすさを格段に向上させることができ、なおかつ再利用可能なコードを作成することにもつながります。もし、プロジェクト全体でこの意識を持ち合わせて取り組むことができたら、「この下位問題を解決するコードを、誰か書いてくれていないかな」と探しに行き、もしあればそれを使用して開発を進めていくことができます。
そうなれば、開発にかかる時間、テストにかかる時間も抑えることができるという結果になります。
抽出した関数に、その下位問題を表す適切な名前を付けてあげることで、元のコードを「説明的なコード」に置き換えることができ、ロジック単位でソースを追うときにはとても役に立つものになります。
私は、エンジニア1年生のころに複雑なロジックを1つのメソッドにずら~っと書いて、ソースレビューで「読んでられない」と指摘を受けて以来、ずっとソースの分解による可読性の向上にこだわっています。もちろんやりすぎるとよくないのは重々承知ですが、改善の効果が十分に得られる程度で、これからも継続していこうと思います。
まとめ
「理解しやすいコード」を書くための手法についていくつか紹介しました。
リーダブルコードでは、他にも「コード全体の美しさ」や「ループとロジックの単純化」など多くの側面から、より理解しやすく、よりよいコードを書くためのアプローチが書かれています。
私としてもとても参考になっている本であり、今も実践している内容が詰まっていてとてもオススメの一冊です。
ぜひ読んでみてください!
読んでいただきありがとうございました。