見出し画像

読みやすいコードを書く上で大事なことを3つ

はじめましての方ははじめまして。いとうと申します。読んだ本のアウトプットをしていきます。あくまで個人的な感想なので異論はめっちゃ認めます。

何を読んだのか

動物の表紙でおなじみのオライリーから出てるリーダブルコードという本で、自分的にめっちゃ納得したものだったりなんとなく思ってたけどそれを言語化してくれた!って本だと思いますし。名著だなーって思いました。

4章 美しさ​

自分の修正担当のコードを探す際など、修正する上で関係ないと思われるソースはササッと読み進めて自分の仕事に集中したいと思います。そんな時に役に立つなぁというイメージ

- 複数のコードブロックで同じようなことをしていたら、シルエットも同じようなものにする。
- コードの「列」を整列すれば、概要が把握しやすくなる

例えば以下RoRでのようなソースがあったとして

id = params[:id]
email = params[:email]
name = params[:name]

↑のソースでもまぁ見にくくはないと思う(わざわざ変数に入れないって言うツッコミも出ると思いますが、、、)。それより↓の方が統一感があって見やすい場面が多いということ。

id    = params[:id]
email = params[:email]
name  = params[:name]

個人的には似ている処理という部分が大事だと思います。なんでもかんでも揃えると読みやすさのメリットよりソース追加するときのデメリットの方が大きくなってしまうような気がします。

5章 コメントすべきことを知る

初めに言うと僕はコメントはほとんど書かない派です。コメントを書く=綺麗で読みやすいコードを諦めている気がして処理の塊が出来たらメソッド化したほうが良いのでは?って思ってる派です。

この章で特に同意するのはソースを読めばわかることをわざわざコメントしないということ。Rubyのソースを用いて説明します。

tags_string = 'note,プログラミング,リーダブルコード'

# 文字列をカンマを区切り文字にして配列にしてeachで標準出力する
tags_string.split(',').each do |n|
   p n
end

上記のような説明はRubyなどのプログラミング言語を知ってる人が見ればすぐわかるはずです。そんなコメントは不要だし、寧ろソースを読む上でノイズになると思います。

その代わりに次にソースを読む人向けになぜ(Why?)そのような処理をしているかを書くほうがよっぽど役に立つ。以下の例ではPost modelのtags_stringと言うカラムに保存されているとします。

post = Post.find(1)

# tags_stringにカンマ区切りで保持しているのでsplitする。
# (データ例): 'note,プログラミング,リーダブルコード'
post.tags_string.split(',').each do |n|
   p n
end

上記のよう書いてあるとわざわざDBの値を知っていなくても、なぜカンマでsplitしているかの意図がわかりやすくなったと思います。そーゆーコメントは良いとされていました。

7章 制御フローを読みやすくする

関数から早く返すという説明がこの章のなかにあります。関数の処理を考えているといろんなパターンを考慮して作らなければならない場合があると思います。パターンを予め考慮して期待値じゃない場合さっさと関数を終わらせるべきだと思います。自信ないですが悪い?例と良い?例を用いて説明してみます。(異論は受け付けてます。)

# パターン1
def discount1(price, discount_percent)
   if discount_percent.nil?
       price
   else
       if discount_percent.class == Integer
           price - (price * discount_percent / 100).floor
       else
           price
       end
   end
end

price = 10000
discount_percents = [nil, 0, 10, 20, 30, 0.10]

discount_percents.each do |percent|
   p discount1(price, percent)
   p discount2(price, percent)
end
# パターン2
def discount2(price, discount_percent)
   return price if discount_percent.nil?
   return price unless discount_percent.class == Integer
   price - (price * discount_percent / 100).floor
end

パターン1, パターン2ともに同じ挙動(なはず)だと思います。けど見比べてみるとパターン2の方が読みやすく、機能を追加する場合でも書きやすいのでは?と個人的には思います。後続の処理で考えるパターンを減らしつつさっさと関数を終了させることは大事だと思います。この処理でパターン2の方が読みやすいと思う理由としては1. ネストが浅い。if elseの分岐が少ないという点だと思います。1も2も同じようなことだと思いますが僕の中では大事であり基本にしていることです。

注意点

私がよくやりがちなのは知った知識をすぐに実行したくなるってことなんですけど、それは手段が目的になってしまうことが多いです。大事なのは必要な時に必要な手段を用いるってことだと思います。

めっちゃ恥ずかしい話だけど、「ワンラインかっけえええ」ってなった時期になんでもかんでもワンラインで書いてしまい後悔しまくってます。どこかでそのソース生きてるかな。。。リファクタリングしてもらえてるのを祈ってますw

最後に

3つくらいにしないと記事書くのにめっちゃ時間かかりそうだったので若めの章から順に抜粋していきました。なのでまだまだめっちゃ面白いことが書かれてます。本の中の具体例のそーすではC#やJavaなどで書かれてましたが、そんなに気にならないのかなーと個人的には思います。

また、読みやすいコードはすぐに身につくものでもないですし1人で実現できるものでも無いと思います。ここでは触れてないですが、特に変数名などは同僚に見てもらったり意見をもらったりが大事とも書かれていました。

読みやすいコードにするべく意識してることなどがあれば色々な人の意見が聞いてみたいなと思っています。