『リーダブルコード』を現場で読み解く! 開発スピードを向上させる、読みやすいコードの書き方【今こそ読み解きたい名著】

圧倒的名著として知られる『リーダブルコード』ですが、高い評価には理由がある!現役エンジニアが、この一冊を読み込み、変数名の命名法など、読みやすいコードを書く極意とその必要性を抽出します。

『リーダブルコード』を現場で読み解く! 開発スピードを向上させる、読みやすいコードの書き方【今こそ読み解きたい名著】

数多くの開発者から支持を受け、読み継がれてきた名著。そこには読み継がれる理由があります。 名著には、内容・ボリュームともに充実した書籍が多く、概要に目を通しただけで本を読んだつもりになっていたり、腰を据えて読む時間がなく「積ん読」してしまいがち。「エンジニアが絶対読むべき書籍●選」といった記事をブックマークするだけで読んだつもりになっていないでしょうか。 ポイントを押さえつつ内容を深掘りし、名著の根底に流れるエッセンスを開発に活かしましょう。

アプリエンジニアの池田惇@jun_ikdです。 エンジニア向け名著を読み解いていく当企画、今回は『リーダブルコード(Dustin Boswell、Trevor Foucher著、角征典訳 オライリー・ジャパン、2012年)から良いコードを書くテクニックを学びます。

リーダブルコード(以下、本書)は、より良いコードを書くためのテクニックがまとめられた一冊です。本稿では、良いコードとは何かについて取り上げ、いくつかの具体的なテクニックや私の経験談を紹介します。すでに実践している方が多いかもしれませんが、コードレビューで他人に伝えるときなどに裏付けとして本書を学んでおくことは価値があると思います。

良いコードとは何か

良いコードとは何かを考えるため、逆に悪いコードとは何か、を考えてみましょう。本書にも悪いコードは以下のように例示されています。

// 与えられた緯度経度に最も近い’array’の要素を返す。
// 地球が完全な球体であることを前提としている。
var findClosestLocation = function (lat, lng, array) {
    var closest;
    var closest_dist = Number.MAX_VALUE;
    for (var i = 0; i < array.length; i += 1) {
        // 2つの地点をラジアンに変換する。
        var lat_rad = radians(lat);
        var lng_rad = radians(lng);
        var lat2_rad = radians(array[i].latitude);
        var lng2_rad = radians(array[i].longitude);

        // 「球面三角法の第二余弦定理」の公式を使う。
        var dist = Math.acos(Math.sin(lat_rad) * Math.sin(lat2_rad) +
                                         Math.cos(lat_rad) * Math.cos(lat2_rad) *
                                         Math.cos(lng2_rad - lng_rad));
        if (dist < closest_dist) {
            closest = array[i];
            closest_dist = dist;
        }
    }
    return closest;
};

『リーダブルコード』 p.130-131より

おそらく多くの方が、以下のように感じるのではないでしょうか。

読みづらい
関数が長く、変数も多い。
どう動いているかわからない
複数の計算が1つの関数内で行われている。
見た瞬間うんざりする
見慣れない公式も登場し、読んで理解するコストが高く感じる。

こうした「悪いコード」に対して、本書では「良いコード」の目的を以下のように述べています。

本書の目的は読みやすいコードを書くことである。その中心となるのは、コードは理解しやすくなければいけないという考えだ。具体的に言えば、誰かが君のコードを読んで理解する時間を最短にするということだ。

『リーダブルコード』はじめに p.xより

先ほど挙げた悪いコードの対極にあたるのが、本書の掲げる「読みやすいコード」です。自分以外の人も理解しやすいコードを書くことでチームの開発効率が上がり、バグも少なくなるでしょう。

良いコードとチーム開発

では、自分以外がコードを理解できているのはどんな状態でしょうか。単に「読めればいい」というわけではありません。

「コードを理解する」というのは、変更を加えたりバグを見つけたりできるという意味だ。他のコードと連携する方法も理解しておかなければいけない。

『リーダブルコード』p.3より

チーム開発では他人が書いたコードを改修することも多く、ソフトウェアは全体が連携して動作します。ですので、手を加えられる状態であることが重要と言えるでしょう。

事業の継続性に関わる

これは私の考えですが、コードの質と事業の継続性には深い関係があると思います。

開発が進むにつれてコード量は増大してきます。うまくコントロールしないと扱いづらくなり、プロダクトの開発スピードが低下します。ちょっとした機能追加に多くの時間がかかってしまい、実装する頃には競合サービスに追い抜かれてしまうかもしれません。

本書でも以下のように述べられています。

プロジェクトは巨大になって、すべてを把握できる人は誰もいなくなる。新しい機能を追加するのが苦痛になってくる。コードを扱うのが厄介になって楽しくなくなる。
(中略)
プロジェクトが成長しても、コードをできるだけ小さく軽量に維持するしかない。

『リーダブルコード』p.171より

事業を継続し、プロダクトの成長を持続させるためには、本書で言われているように、できるだけ小さく軽量な、良いコードが必要なのではないでしょうか。

ここからは本の中で取り上げられている理解しやすいコードを書くためのポイントと実際の例をいくつか紹介します。代表的なテクニックを見ていきましょう。

変数と理解しやすさ

まずは変数を取り上げます。すぐに取り組める内容なので、初めにやってみるといいでしょう。

変数名に具体的な情報を込める

変数名にどんな英単語を使うべきか悩むケースは少なくないはず。本書では使う単語を工夫し、分かりやすい名称にするコツを紹介しています。

例えば、「get」はあまり明確な単語ではない。

def GetPage(url);

「get」という単語からは何も伝わってこない。このメソッドはページをどこから取ってくるのだろう? ローカルキャッシュから? データベースから? インターネットから? インターネットから取ってくるのであれば、FetchPage()やDownloadPage()のほうが明確だ。

『リーダブルコード』p.10-11より

意味がはっきり通る単語を変数名に使うだけで、コードを読む人へのメッセージになるのです。

本書では、より伝わりやすい単語の代替案として以下の例が挙げられています。

1

『リーダブルコード』p.12 をもとに表を作成

例えば表中のstartを代替案に置き換えると、私の感覚では以下のようなイメージを持てます。

launch
起動する、新たに立ち上げる
例) アプリケーションの起動
create
今存在しないものを作り出す
例) データやオブジェクトの生成
begin
繰り返しや終わりのある処理が始まる
例) タイマー処理の開始
open
新たにオブジェクトを利用する
例) ファイルやDBの利用開始

このように、より具体性の高い単語を使うことで名前から得られる情報量を増やすことができます。

省略形を使う

例えば変数名でHyperTextMarkupLanguageと書くことはなく、HTMLという省略形を用いると思います。このような省略形を用いるかどうか、いかに判断するべきでしょうか。

 ぼくたちの経験からすると、プロジェクト固有の省略形はダメだ。
(中略)
 新しいチームメイトはその名前の意味を理解できるだろうか? 理解できるなら問題ない。
 プログラマは、evaluationの代わりにevalを使う。documentの代わりにdocを使う。stringの代わりにstrを使う。だから、新しいチームメイトもFormatStr()の意味は理解できる。でも、BEManagerの意味は理解できない。

『リーダブルコード』p.24より。本書で指す “BEManager” はBackEndManagerという意味

指針として、プロジェクト外でも広く使われている省略形は使い、プロジェクト独自の省略形は避けるべきと述べられています。

自分のチームやプロダクトで当たり前に使っている省略形だとしても、新しいメンバーが加わった際に理解できるか考えてみるのが良いと思います。例えば、組織名や社内技術等の略称は新メンバーには理解できません。多用せずに最小限にとどめておくのが良いでしょう。

変数のスコープを縮める

変数のスコープも小さいほど良いとされています。

変数のことが見えるコード行数をできるだけ減らす。
(中略)
アクセスはできるだけ制限して、変数のことが「見えてしまう」コードを減らすのがいいとされている。
 では、なぜそうするのがいいとされているのだろう? それは、一度に考えなければいけない変数を減らせるからだ。

『リーダブルコード』p.115-116より

クラスのメンバ変数の例を引用します。まず、悪い例です。

class LargeClass {
    string str_;

    void Method1() {
        str_ = …;
        Method2();
    }

    void Method2() {
        // str_ を使っている
    }

    // str_ を使っていないメソッドがたくさんある    
}

『リーダブルコード』p.116より

メンバ変数str_はクラス内のどこからでもアクセスできます。しかし、実際に使用しているのはMethod1()Method2()のみです。

では、以下はどうでしょうか。

class LargeClass {
    void Method1() {
        string str = …;
        Method2(str);
    }

    void Method2(string str) {
        // str を使っている
    }

    // その他のメソッドはstrが見えない。
}

『リーダブルコード』p.116より

Method1にローカル変数としてstrを定義し、Method2には引数として渡す形になりました。その他のメソッドからはstrが見えないため、前の例よりも変数のスコープを縮めることができています。

式と関数

エンジニアHubに会員登録すると
続きをお読みいただけます(無料)。
登録のメリット
  • すべての過去記事を読める
  • 過去のウェビナー動画を
    視聴できる
  • 企業やエージェントから
    スカウトが届く