4
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

読みやすいコードを書く

僕はエンジニアを志している大学4年生(2020年6月現在)です。
内定先の会社の先輩に、誕生日プレゼントとして「リーダブルコード」を買っていただきました。
メモを取りながら3回くらい読んだので、それをまとめて記事にしてみます。

名前に情報を詰め込む

  • 明確な意味を示す単語を選ぶ
  • 汎用的で、誤解を招くような意味の単語を避ける

明確な意味を示す単語を選ぶ

  • get ではなく fetchdownload を選ぶ
  • size ではなく heightnum を選ぶ

汎用的で、誤解を招くような意味の単語を避ける

  • tmp
    • 一時的な保持が大切な変数にだけ使う
    • このような名前を使うときは、それ相応の理由を用意する
  • ループイテレータ(i, j, k)は基本的には問題ない
    • ただし、例えばクラブに所属しているユーザを調べるループなら、以下のような変数名が良い
      • club_i
      • member_i
      • user_i

誤解されない名前をつける

その名前が「他の意味と間違えられることはないだろうか?」と何度も自問自答する。

  • filter ではなく selectexclude を使う
  • 限界値を含めるときは minmax を使う
  • 範囲を指定するときは firstlast を使う
  • ブール値の変数名は、頭に次のような単語を付けると分かりやすい
    • is
    • has
    • can
    • should

美しさを意識する

  • 一貫性のあるレイアウトを使う
    • 一貫性のある改行位置にする
    • 並び方、順番に意味を持たせる
      • 対応するHTMLフォームのフィールドと同じ並び順
      • 「最重要」なものから重要度順
      • アルファベット順
  • 似ているコードは、似ているように見せる
    • 空白文字を使って、縦の線を真っ直ぐにする(引数の位置を揃える、など)
  • 関連するコードをまとめてブロックにする
    • 空行を使うことで、論理的な「段落」に分ける
    • 段落ごとに要約コメントを追加するのも有効

コメント

原則

  • コメントの目的は、書き手の意図を読み手に知らせること。
    • なぜ他のやり方ではなく、こうなっているのか
    • 懸念や欠陥と思われるもの
    • それにまつわる背景など
  • コードを見てすぐに分かることを、わざわざコメントに書かない
  • 優れたコード > ひどいコード + 優れたコメント
  • 読み手の立場になって考える
    • 質問されそうなこと、その答え
    • 間違える可能性のあること
    • 全体像についての簡単な解説
    • 関数やクラスなどについての要約
    • その他コードを理解するのに役立つあらゆる情報

正確で簡潔に

  • 曖昧な代名詞を避ける
    • そのそれ を具体的な表現に変える
  • 関数の説明に、実際の具体例を使うのは有効
    • 例)この引数に対して、この値を返す
  • 引数にコメントをつける(と分かりやすいこともある)

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

  • 条件式の引数の並び順
    • 左:調査対象、変化するもの
    • 右:比較対処、あまり変化しないもの
  • if / else ブロックの並び順
    • 条件は否定形よりも肯定形を使う
    • 単純な条件を先に書く。if と else が同じ画面に表示されて見やすい
    • 関心を引く、目立つ条件を先に書く
      • 具体的な値を使うときなど
  • 三項演算子はなるべく使わない
    • ただし、簡潔になるときは使っても問題ない
  • do / while ループを避ける
    • while ループで書き直せることが多い
  • ネストを浅くする
    • 早めに返してネストを削除する
      • 関数で複数のreturn文を使っても問題ない
    • continue でループ内部のネストを削除する

巨大な式を分割する

  • 式を表す変数を使う(説明変数)
  • 式を変数に代入しておく(要約変数)
  • ド・モルガンの法則を使う
    • not (A or B or C) = (not A) and (not B) and (not C)
    • not (A and B and C) = (not A) or (not B) or (not C)
  • 「頭が良い」コードに気をつける
    • 「頭が良い」=「一見だと分かりづらい」
    • あとで他の人が読むときに分かりにくくなる

式を表す変数を使う(説明変数)

例えば、以下の左辺は何を指しているか分かりづらい。

if line.split(':')[0].strip() == "root":

これをあらかじめ、説明された変数に代入しておく。

username = line.split(':')[0].strip()
if username == "root":

式を変数に代入しておく(要約変数)

以下の例では式は長くないが、もっと良くできる。

if (request.user.id == document.owner_id) {
    // ユーザはこの文書を編集できる
}

...

if (request.user.id != document.owner_id) {
    // 文書は読み取り専用
}

この式が言いたいことは「ユーザは文書を所持しているか?」である。
そこで、要約した変数を追加して、もっと明確なコードにすることができる。

final boolean user_owns_document = (request.user.id == document.owner_id);
if (user_owns_document) {
    // ユーザはこの文書を編集できる
}

...

if (!user_owns_document) {
    // 読み取り専用
}

変数と読みやすさ

  • 変数の数を減らす
    • 数が多いと追跡するのが難しくなる
  • 変数のスコープを小さくする
    • 変数のスコープが大きいと、把握する時間が長くなる
    • できるものは、ローカル変数に「格下げ」する
    • 大きなクラスを、小さなクラスに分割する
    • クロージャを使う
      • 変数を関数内に入れて、アクセスできる範囲を縮める
    • 使う直前で、変数を定義する
  • あまり変数を頻繁に変更しないようにする
    • 頻繁に変更されると、現在の値を把握するのが難しくなる
    • 一度だけ書き込むようにする
      • constfinal を使う
      • 「永続的に変更されない」変数は扱いやすい

一度に1つのことを

コードは1つずつタスクを行うようにしなければならない。

  1. コードが行っているタスクを全て列挙する
  2. それぞれのタスクをできるだけ異なる関数に分割する
  3. 分割できないものは、異なる領域に分割する

コードに思いを込める

おばあちゃんに分かるように説明できなければ、本当に理解したとは言えない
by アルバート・アインシュタイン

  1. コードの動作を簡単な言葉で同僚にも分かるように説明する
  2. その説明の中で使っているキーワードやフレーズに注目する
  3. その説明に合わせてコードを書く

短いコードを書く

  • 必要になりそうな機能の実装について悩まないようにする
    • YAGNI原則
      • 今の時点で必要のない機能は実装しない
      • 必要になったら実装する
  • 要求の分割
    • 最も簡単に問題を解決できるような要求を考える
    • 問題を解決できるのであれば、多少の厳密さは失われても問題ない
  • コードを小さく保つ
    • 重複コードを削除する
    • 未使用のコードや無用の機能を削除する

テストと読みやすさ

  • テストを読みやすくて保守しやすいものにする
    • 他のプログラマが安心してテストの追加や変更ができるように
  • エラーメッセージを読みやすくする
    • もし使えるのであれば、便利なアサーションメソッドを使うべき
    • 手作りのエラーメッセージを作る
  • テストの適切な入力値を選択する
    • 入力値を単純化する
    • 1つの機能に複数のテスト
      • 完璧な入力値を1つ作るよりも簡単で効果的で読みやすい
  • テストの機能に名前をつける
    • Test1() ではなく Test_SortAndFilterDocs() のようにする
  • テストに優しい開発をする
    • テストしやすいようにコードを設計する
      • 振る舞いごとに上手く分割される
      • 自然に良いコードが書けるようになる

おわりに

この「リーダブルコード」という本は、とても勉強になりました。
読みやすいコードを書くためのヒントが盛りだくさんでした。

ただ1つ思ったのは、知識があるだけでは良いコードは書けないだろうということです。
大切なことは、やはり多くのコードを書くこと、すなわち経験値だと思いました。
この本から学んだことを意識しながら、これから経験を積んでいきたいと思います。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
4
Help us understand the problem. What are the problem?