3章 誤解されやすい名前
鍵となる考え
**「名前が他の意味と間違えられることはないだろうか?」**と何度も自問自答する。
→ 積極的に「誤解」を探して、あいまいな名前、間違った名前を減らす
例: filter()
filter()という言葉では、選択するのか、除外するのかがわからない。(つまり、あいまい)
resultls = Database.all_objects.filter("year <= 2011");
選択するのであれば、 select() にした方が良い。
除外するのであれば、 exclude() にした方が良い。
限界値を含めるときはminとmaxを使う
ショッピングカートには商品が10点までしか入らないとする。
✗ CART_TOO_BIG_LIMIT = 10
◯ MAX_ITEMS_IN_CART= 10
アドバイス: 限界値を明確にするには、名前の前に max_ や min_ を付けよう。
範囲を指定するときはfirstとlastを使う
包含の意味を含むのであれば、範囲を指定するときはfirstとlastを使用した方が良い。
set.PrintKeys(first="Bart", last="Maggie");
包含/排他的範囲には begin と end を使う
包含・排他的範囲 (最初を含むが、最後の要素は含まない)の場合は beginとendを使うのが良い。
ブール値の名前
✗ read_password
◯ need_password, user_is_authenticated
is, has, can, should をつけておけばOK
ブール値の名前
否定形は避けよう
✗ disable_ssl
◯ use_ssl
肯定形にしたほうがわかりやすい(Swiftのguardとかにも言えることかもね)
ユーザ(使用者)の期待に合わせる
get〇〇()、〇〇.list()、〇〇.size()
は軽量なメソッドであると大抵のプログラマーは思う(らしい)
なので、重い場合は
generate〇〇()、〇〇.countSize()、〇〇.countElement()
とかにすべし
複数の名前を検討する
類義語調べて比較して適切なものを選べ
まとめ
- 最善の名前は誤解されない名前
- ✗ filter, limit, length
- ◯ max, min, first, last, begin, end
- Bool値が返るなら is や has をつける
- disable_ssl のような否定形は避ける
- get() や size() のようなメソッド名なら軽量を期待される
- 名前は大事だからよく検討しろ
4章 美しさ
鍵となる考え
一貫性のあるスタイルは「正しい」スタイルよりも大切だ
→ どちらの書き方が正しいのかなんてのは一貫性の前ではゴミ同然
鍵となる考え
優れたソースコードは「目に優しい」ものでなければならない
→ 余白、配置、順序に気を使おう!
なぜ美しさが大切なのか
プログラミングのほとんどの時間はコードを読む時間であり、それでいうと読みやすさを追求するのはあたりまえのこと。
また、設計に比べ容易に導入できるので今すぐに取り組むべきである。
メソッドを使った整列
だめな例
DatabaseConnection database_connnection;
string error;
assert(ExpandFullName(database_connection, "Doug Adams", &error) == "Mr. Douglas Adams");
assert(error == "");
assert(ExpandFullName(database_connection, "Jake Brown", &error) == "Mr. Jacob Brown Ⅲ");
assert(error == "");
assert(ExpandFullName(database_connection, "No Such Guy", &error) == "");
assert(error == "no match found");
メソッドを使った整列
良い例
CheckFullName("Doug Adams", "Mr. Douglas Adams", "");
CheckFullName("Jake Brown,", "Mr. Jake Bron III", "");
CheckFullName("No Such Guy", "", "no match found");
CheckFullName("John", "", "more than one result");
void CheckFullName(...) {
...
}
メソッドを使った整列
まとめ
- 重複がなくなり簡潔になった
- テストケースの大事な部分に目がいきやすくなった(差分がわかりやすい)
- テストの追加がしやすくなった
縦の線を整列する
CheckFullName("Doug Adams" , "Mr. Douglas Adams", "");
CheckFullName(" Jake Brown,", "Mr. Jake Bron III", "");
CheckFullName("No Such Guy" , "" , "no match found");
CheckFullName("John" , "" , "more than one result");
リーダブルコードではおすすめしているが、今のIDEとは相性が悪いので個人的にはあまり好きではない
一貫性と意味のある並び
一連の同じデータを使用する際は並び順も同じにしておく
details = request.POST.get('details');
locations = request.POST.get('locations');
phone = request.POST.get('phone');
if details: rec.details = details
if phone: rec.phone = phone
if locations: rec.locations = locations
コードを段落に分割する
だめな例
def suggest_new_friends (user, email_password):
friends = user.friends()
friend_emals = set(f.email for f in friends)
contacts = import_contacts(user.email, email_password);
contact_emals = set(c.email for c in contacts)
non_friend_emails = contact_emals - friend_emails
suggested_friends = USer.objects.select(email__in=non_friend_emails)
display['user'] = user
display['friends'] = friends
display['suggested_friends'] = suggested_friends
return render("suggested_friends.html", display)
コードを段落に分割する
良い例
def suggest_new_friends (user, email_password):
# ユーザの友達のメールアドレスを取得する。
friends = user.friends()
friend_emals = set(f.email for f in friends)
# ユーザのメールアカウントからすべてのメールアドレスをインポートする。
contacts = import_contacts(user.email, email_password);
contact_emals = set(c.email for c in contacts)
# まだ友達になっていないユーザを探す。
non_friend_emails = contact_emals - friend_emails
suggested_friends = USer.objects.select(email__in=non_friend_emails)
# それをページに表示する
display['user'] = user
display['friends'] = friends
display['suggested_friends'] = suggested_friends
return render("suggested_friends.html", display)
コードを段落に分割する
まとめ
- 段落単位でコードを読むことが可能に
- 必要な箇所だけ読んで、不要な箇所は読まなくて済む
- ってか、段落にするならもはやメソッドに分けたほうが良くね?
まとめ
- コードの美しさはコードの理解を助ける
- 同じ処理は同じシルエットにする
- 意味のある順序でコードを書く
- 空行を使ったブロック分けも倫理的な段落を意識する
参考
「リーダブルコード」を読む (第3章「理解しやすいコード」第4章「美しさ」) - FPGA開発日記
http://msyksphinz.hatenablog.com/entry/2017/11/19/230337