読みやすいコードを書く
僕はエンジニアを志している大学4年生(2020年6月現在)です。
内定先の会社の先輩に、誕生日プレゼントとして「リーダブルコード」を買っていただきました。
メモを取りながら3回くらい読んだので、それをまとめて記事にしてみます。
名前に情報を詰め込む
- 明確な意味を示す単語を選ぶ
- 汎用的で、誤解を招くような意味の単語を避ける
明確な意味を示す単語を選ぶ
-
get
ではなくfetch
やdownload
を選ぶ -
size
ではなくheight
やnum
を選ぶ
汎用的で、誤解を招くような意味の単語を避ける
-
tmp
- 一時的な保持が大切な変数にだけ使う
- このような名前を使うときは、それ相応の理由を用意する
- ループイテレータ(
i
,j
,k
)は基本的には問題ない- ただし、例えばクラブに所属しているユーザを調べるループなら、以下のような変数名が良い
club_i
member_i
user_i
- ただし、例えばクラブに所属しているユーザを調べるループなら、以下のような変数名が良い
誤解されない名前をつける
その名前が「他の意味と間違えられることはないだろうか?」と何度も自問自答する。
-
filter
ではなくselect
やexclude
を使う - 限界値を含めるときは
min
とmax
を使う - 範囲を指定するときは
first
とlast
を使う - ブール値の変数名は、頭に次のような単語を付けると分かりやすい
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) {
// 読み取り専用
}
変数と読みやすさ
- 変数の数を減らす
- 数が多いと追跡するのが難しくなる
- 変数のスコープを小さくする
- 変数のスコープが大きいと、把握する時間が長くなる
- できるものは、ローカル変数に「格下げ」する
- 大きなクラスを、小さなクラスに分割する
- クロージャを使う
- 変数を関数内に入れて、アクセスできる範囲を縮める
- 使う直前で、変数を定義する
- あまり変数を頻繁に変更しないようにする
- 頻繁に変更されると、現在の値を把握するのが難しくなる
- 一度だけ書き込むようにする
-
const
やfinal
を使う - 「永続的に変更されない」変数は扱いやすい
-
一度に1つのことを
コードは1つずつタスクを行うようにしなければならない。
- コードが行っているタスクを全て列挙する
- それぞれのタスクをできるだけ異なる関数に分割する
- 分割できないものは、異なる領域に分割する
コードに思いを込める
「おばあちゃんに分かるように説明できなければ、本当に理解したとは言えない」
by アルバート・アインシュタイン
- コードの動作を簡単な言葉で同僚にも分かるように説明する
- その説明の中で使っているキーワードやフレーズに注目する
- その説明に合わせてコードを書く
短いコードを書く
- 必要になりそうな機能の実装について悩まないようにする
- YAGNI原則
- 今の時点で必要のない機能は実装しない
- 必要になったら実装する
- YAGNI原則
- 要求の分割
- 最も簡単に問題を解決できるような要求を考える
- 問題を解決できるのであれば、多少の厳密さは失われても問題ない
- コードを小さく保つ
- 重複コードを削除する
- 未使用のコードや無用の機能を削除する
テストと読みやすさ
- テストを読みやすくて保守しやすいものにする
- 他のプログラマが安心してテストの追加や変更ができるように
- エラーメッセージを読みやすくする
- もし使えるのであれば、便利なアサーションメソッドを使うべき
- 手作りのエラーメッセージを作る
- テストの適切な入力値を選択する
- 入力値を単純化する
- 1つの機能に複数のテスト
- 完璧な入力値を1つ作るよりも簡単で効果的で読みやすい
- テストの機能に名前をつける
-
Test1()
ではなくTest_SortAndFilterDocs()
のようにする
-
- テストに優しい開発をする
- テストしやすいようにコードを設計する
- 振る舞いごとに上手く分割される
- 自然に良いコードが書けるようになる
- テストしやすいようにコードを設計する
おわりに
この「リーダブルコード」という本は、とても勉強になりました。
読みやすいコードを書くためのヒントが盛りだくさんでした。
ただ1つ思ったのは、知識があるだけでは良いコードは書けないだろうということです。
大切なことは、やはり多くのコードを書くこと、すなわち経験値だと思いました。
この本から学んだことを意識しながら、これから経験を積んでいきたいと思います。
Author And Source
この問題について(読みやすいコードを書く), 我々は、より多くの情報をここで見つけました https://qiita.com/yuya_yuzen/items/9ef683bf2a5cc5b301c1著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .