初めまして。2020年4月NewsPicksに新卒エンジニアとして入社した崔(チェ)です。
実は私は、大学では語学を専攻し大学院から情報系に進学したもので、入社当時コーディング歴2年という浅い経験しかありませんでした。 そんな中、むしろ変な癖のついてない今だからこそ基礎的な技術書を読んで学んでいけばいいと 『リーダブルコード』 をオススメいただきました。
今回はその 『リーダブルコード』 を読んで現場でのコーディングについての知見を得た話を書いていきます。
内容整理
『リーダブルコード』 は、大きく 「理解しやすい・可読性の良いコードの書き方(特に会社で開発する際)」 と 「テストコードの重要性」 の話に分けられます。
理解しやすいコード書こう
1. そもそも読みやすいコードって何?
『リーダブルコード』 では、読む時間が短いコードではなく、理解する時間が短いコードが良いコードだと述べています。
つまり6ヶ月後の自分が見ても一発で理解できるコードなのか自問自答してみて問題ないなら、読みやすいコードと判断していいということです。
これは 『リーダブルコード』 を読む前、上司や先輩からアドバイスいただいた話でもありました。 特にコードレビューいただいたときに聞いたのが、
- 人間が文書を読む習慣(上から読んでいくなど)を考慮してコード実装した方がわかりやすい
- 変数にしなくても良いけど、した方がわかりやすいのであれば、あえて変数にした方がいい ←
説明変数
というこだったので、この本が述べようとしてる内容と一致していたのです。
2. 命名
『リーダブルコード』 以外にオススメいただいていた『SICP』の1章でも何回も強調されていたのが、命名です。
しかし、この2冊には一点の違いがあります。
『SICP』 は可能な限り汎用的で抽象的
に命名すべきであると述べ、 『リーダブルコード』 はできる限り汎用的な名前を避け具体的
にすべきであると述べている点です。
『リーダブルコード』 が汎用的な名前を避け具体的に
すべきであると述べているのは、以下の理由からです。
変数のタイプを教えるため
- 中間値を出力しなくとも、コードを読むだけでわかるようにしたいから
- e.g.
date_list
,date_set
単位を教えるため
- ただの
size
なら何を言っているのか分からないから - e.g.
delay_secs
,size_mb
,max_kbps
- ただの
なるべく明確に書いた方が、その役割がわかるため
- e.g.
get_mean()
だとこれから計算して取得するのか、既に計算された値を取得するだけなのか分からないので、compute_mean()
などにする
- e.g.
ではどうして 『SICP』 と 『リーダブルコード』 の主張に差が生じているのか上司に聞いてみると、 『SICP』 は教科書的な本であり、 『リーダブルコード』 は現場で役立つ情報を詰めた本であるためと教えてくださいました。
実際、以上の例のようにデータ型を変数名に詰め込むスタイルは、当時私の所属チームの実装していたアーキテクチャでも取り入れられていて、コードレビューでも同じアドバイスをいただいたことがありました。
これらを読んで思ったのは、 『SICP』 と適切に混ぜていい名前を頑張って考えよう、ということでした。
3. 美しいコード
美しく可読性の良いコードを書くため、以下を注意する必要があります:
- 似ているコードは似ているように見せる
- 関連するコードをまとめてブロック(段落)にする
- たまにメソッドとメソッドの間だけをあけたスクリプトを見かけますが、その度ブロックの大事さがわかったりします。
私はPythonユーザなのですが、この本の美しいコード
の例として挙げられた以下スタイルに関しては同意できません:
details = response.get('details') location = response.get('location') phone = response.get('phone')
なぜなら、このように記号の位置を合わせるのは、PEP8で「推奨しlない」ものだからです。 各言語で推奨しているルールに従いましょう。
4. コメント
コードだけで完璧に理解できるコードを実装するのが一番の理想なのですが、コメントを書いた方がいい瞬間というのも確かに存在します。
- 監督コメンタリー:いくつかの似たモジュールの中であえて今のを選んだ理由を明示
コードの欠陥を表示
TODO
:後で手をつけるFIXME
:既知の不具合があるコードHACK
:推奨されない解決策XXX
:危険!
ハイパーパラメータの数字など
- e.g.
# 人間はこんなに読めない
(1000)
- e.g.
ハマりそうなところを告知
- e.g.
# メールを送信する外部サービスを呼び出している(1分でタイムアウト)
- e.g.
# 実行時間はO(タグの数 * タグの深さの平均)なので、ネストの深さに気をつける
- e.g.
ロジックを要約
開発者の意図の共有
以上を踏まえて以下を気をつけると、くどくないいいコメントを書くことができるようになります。
- 曖昧な代名詞は避ける
- 簡潔に書く
- 動作を正確に書く
- 実例を挙げる
- 情報密度の高い言葉を使う
- AvenueならAve.にする
5. ロジックの単純化
ロジックを単純化するためまず、ループを読みやすく簡潔にすることが必要です。この部分を読んで,以前コードレビューのためのペアプロで、既にアドバイスいただいていた内容だったことを思い出しました。
- スコープを最小限にする
- 肯定条件(関心を引く条件から)から書く
- 短い方を先に書いてネストを浅くする ← ここまでがアドバイスいただいた内容と一致しています。
- 比較対象を左に書く
- これについて、例えば以下の3行目のように書けるのなら、この規則は守らない方が読みやすいのではないか、と思っています。
return end > other.begin and end <= other.end # これって下のように書いた方が、比較範囲がはっきりしていて、わかりやすくないか? return other.begin < end <= other.end
次に、一つのメソッドには一つの機能だけを実装する。
複数のプロセスをこなしているなら、メソッドを分割する
- でもやりすぎたら可読性を損なうので、分割しすぎてはいけない
メソッド間やクラス間での依存関係を最低限に抑える
- これについても、既にコードレビューでアドバイスいただいておりました。
- 依存関係を避けるため、なるべく、クラスの中で別のクラスをインスタンス化することなく、既に初期化したものを渡して使うように実装した方がいいということでした。
汎用コードを書いて再活用する
- 『SICP』 でもすごく強調していた内容です。
built-inライブラリを調べ、自分に必要なものを探し、積極的に使う
ロジックを実装する前に、まず言葉で説明する
- できれば実装スクリプトは細かくレビューしてもらう
- ↑これは、タイミング良く 『リーダブルコード』 を読み上げる頃、タスク・PRを細かく分割してレビューリクエストした方が、考慮漏れなく、レビュー・レビュー対応の質も上がることに気づき、今も実践中です。
自分のコードとそれを実装した時間がもったいなく思えるかもしれないが、必要ないコードはすぐ削除する習慣を持つ
良いテストコードを書こう
可読性の良いコードを書くことも重要ですが、それを仕切りにテストし、常に改善・保守できる状態にすることも大事です。 テストコードを踏まえて開発した方が、安全であるためです。
ですが、ただそこに存在するだけのクオリティだと、それを修正するのを徐々に怠けてしまうので、本番のコードに問題があっても直さず放置するようになります。 よって、テストコードも実際処理を行うコード並みに綺麗に書く必要があります。
『リーダブルコード』 で挙げている良いテストコードの特徴は以下です:
- テスト自体に必要ない情報は徹底的に隠す
挙動を変える最低限の引数以外は引数にしない(テスト対象)
- そうしないと、テスト時にテストと関係のない情報が必要になるので
単純に
assert
してしまっては、エラーの詳細が見えないので、テストツールを積極的に取り入れる- pytestなど
渡す値は最大限簡潔にする
- e.g. ネガティブ値が通るか試したいだけなのに
-1999985.4
を渡す必要はない
- e.g. ネガティブ値が通るか試したいだけなのに
テスト機能に名前をつける
- e.g.
TestSortAndFilterDocs()
ではなく、TestSortAndFilterDocsBasicSorting()
やTestSortAndFilterDocsNegativeValues()
にする- 個人的には↑の例は具体的すぎて冗長に思えます。
- e.g.
つまり、表面的に見てこれが何をテストするためのコードかが一発でわかるように実装すべきなのです。
『リーダブルコード』 で勧めている次に読んだ方がいい本
もっといろんな本がリストアップされていますが、その中でも今の自分が興味をもったのは以下です:
『リファクタリングープログラムの体質改善テクニック』
『達人プログラマー』
- 半分くらい読んだ状態なのですが、とてもためになる本です!
『オブジェクト指向における再利用のためのデザインパターン』
『珠玉のプログラミング 本質を見抜いたアルゴリズムとデータ構造』
『ハイパフォーマンスWebサイトー高速サイトを実現する14のルール』
最後に
ユーザベースではエンジニアを募集中です。ご興味がございましたら、UzabaseのCareerページをぜひご覧ください。「エンジニア」で検索してもらえればと思います。