【読書メモ】リーダブルコード その4
リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック 最終回です。
リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)
- 作者: Dustin Boswell,Trevor Foucher,須藤功平,角征典
- 出版社/メーカー: オライリージャパン
- 発売日: 2012/06/23
- メディア: 単行本(ソフトカバー)
- 購入: 68人 クリック: 1,802回
- この商品を含むブログ (140件) を見る
8章 巨大な式を分割する
巨大な式は飲み込みやすい大きさに分割する
8.1 説明変数
式を簡単に分割するには、式を表す変数を使えばいい。この変数を「説明変数」と呼ぶこともある。式の意味を説明してくれるからだ。
var str = 'root:' if (str.replace(':','') === 'root') { ... } // ↓↓↓ 説明変数を使う var str = 'root:' var username = str.replace(':',''); if (username === 'root') { ... }
これを使うと、
- 巨大な式を分割できる。
- 簡潔な名前で式を説明することで、コードを文書化できる。
- コードの主要な「概念」を読み手が認識しやすくなる。
8.2 要約変数
式を説明する必要がない場合でも、式を変数に代入しておくと便利だ。大きなコードの塊を小さな名前に置き換えて、管理や把握を簡単にする変数のことを要約変数と呼ぶ。
if (request.user.id === document.owner_id) { } // ↓↓↓ 要約変数を使う var userOwnDocument = request.user.id === document.owner_id; if (userOwnDocument) { ... }
8.6 巨大な文を分割する
- タイプミスを減らすのに役立つ
- 横幅が縮まるのでコードが読みやすくなる。
- クラス名を変更することになれば、一箇所を変更すればいい。
これまでに無意識でやるときとやらない時がありましたが、ちゃんとやろうと思いました。
var update_highlight = function (message_num) { if($("#vote_value" + message_num).html() === "Up") { $("#thumbs_up" + message_num).addClass("highlighted"); $("#thumbs_down" + message_num).removeClass("highlighted"); } else if ($("#vote_value" + message_num).html() === "Down") { ... }; // ↓↓↓ 同じ式は要約変数として関数の最上部に抽出する var update_highlight = function (message_num) { var thumbs_up = $("#thumbs_up" + message_num); var thumbs_down = $("#thumbs_down" + message_num); var vote_value = $("#vote_value" + message_num).html(); var hi = "highlighted"; if(vote_value === "Up") { thumbs_up.addClass(hi); thumbs_down.removeClass(hi); } else if (vote_value === "Down") { ... };
9章 変数と読みやすさ
- 変数が多いと変数を追跡するのが難しくなる。
- 変数のスコープが大きいとスコープを把握する時間が長くなる。
- 変数が頻繁に変更されると現在の値を把握するのが難しくなる。
9.1 変数を削除する
8章で 説明変数
や 要約変数
を使って巨大な式を分割して説明文のようにしたため、読みやすくなった。
逆に、複雑な処理を分割していない変数などは変数にする必要はない。
now = datetime.datetime.now() root_message.last_view_time = now
この
now
を使う意味があるだろうか?意味がない理由を以下に挙げよう。
- 複雑な式を分割していない。
- より明確になっていない。
datetime.datetime.now()
のままでも十分に明確だ。- 一度しか使っていないので、重複コードの削除になっていない。
9.2 変数のスコープを縮める
変数のことが見えるコード行数をできるだけ減らす
これあんまり理解できなかったのですが、
- グローバル変数は避ける
- アクセスはできるだけ制限して、変数のことが「見えてしまう」コードを減らすのがいいとされている。
変数を操作する場所が増えると、現在地の判断が難しくなる。
で触れられている
変数は一度だけ書き込む
というルールは、ES5では const
と let
でだいぶ解決されたのかなと思う。
10章 無関係の下位問題を抽出する
エンジニアリングとは、大きな問題を小さな問題に分割して、それぞれの解決策を組み立てることに他ならない。
本章のアドバイスは、無関係の下位問題を積極的に見つけて抽出する ことだ。
- 関数やコードブロックを見て「このコードの高レベルの目標は何か?」と自問する。
- コードの各行に対して「高レベルの目標に直接的に効果があるのか?あるいは、無関係の下位問題を解決しているのか?」を自問する。
- 無関係の下位問題を解決しているコードが相当量あれば、それらを抽出して別の関数にする。
という技法で大幅にコードを改善できる。
とのこと。あまり上位/下位問題など考えたことなかったので新しい発見です。
10.3 その他の汎用コード
ajax_post({ url: '', data: data, on_success: function (response_data) { var str = "{"; for(var key in response_data) { str += " " + key + " = " + response_data[key] + "¥n"; } alert(str + "}"); // 引き続き response_dataの処理 } });
このコードの高レベルの目標は「サーバをAjaxで呼び出してレスポンスを処理する」である。
でも、このコードの大部分は「ディクショナリをキレイに印字(pretty print
する)」という「無関係の下位問題」を解決しようとしている。
var format_pretty = function(obj) { var str = "{"; for(var key in response_data) { str += " " + key + " = " + response_data[key] + "¥n"; } return str + "}"; }
こうすると、
- 呼び出し側のコードが簡潔になる
format_pretty()
をあとから再利用できる- コードが独立していれば、
format_pretty()
の改善が楽になる
という恩恵を受けることができる。(特に最後の「改善が楽になる」が大事)
11章〜15章は省略。。
全体の感想など
これまで全く意識していなかったこと、少しは意識していたけど言語化できなかったり、論理的に考えていなかったことが発見できて良かったです。
まだ勉強不足で読んでもしっくりこない箇所もありましたが、これからのコーディングをしていくなかでの指針みたいなもの(困ったらすがるもの)ができたので、そこが一番よかったことかなと思います。