はじめに
今回は「リーダブルコード」を拝読したためそこで学んだ「より良い」コードを書くためのテクニックを、特に自分のような初心者からでもすぐに取り入れられそうなものをピックアップし、アウトプットします。
1. 理解しやすいコード
鍵となる考え
- コードは理解しやすくなければならない
- コードは他の人が最短時間で理解できるように書かなければならない
大切な事
- 「このコードは理解しやすいか」と自問自答する
- コードの短さより、理解するまでにかかる時間の短い方がよりいい
2. 表面上の改善
2.1 名前に情報を詰め込む
できること
1. 明確な単語を選ぶ
例: start -> launch, create, begin, open
2. 重要な属性の追加
単位などの例: delay -> delay_secs
その他の例 : password -> plaintext_password
2.2 誤解されない名前
できること
1. 限界値を含めるときはmin, maxを使う
limitだと限界値を含むか含まないか曖昧
2. 範囲を指定するときはfirstとlastを使う
stopではなくlastを使えば包含していることが明確(min,maxでも可)
3. 包含、排他的範囲(含まない)にはbegin, endを使う
4. bool値の名前を否定形にしない
例: bool disable_ssl = false (ややこしい)
2.3 美しさ
できること
1. 一貫性のある簡潔な改行位置
数値の位置を上下で一貫性を持たせている例:
//TcpConnectionsSimulator(throughput, latency, jitter, packet_loss);
// [kbps] [ms] [ms] [percent]
public static final TcpConnectionSimulator ts_filter =
new TcpConnectionsSimulator(45000, 10, 0, 0);
public static final TcpConnectionSimulator ts_filter =
new TcpConnectionsSimulator(45000, 400, 250, 5);
2. 縦の線をまっすぐにする
複数の変数を定義している例:
details = request.POST.get('details')
location = request.POST.get('locaiton')
phone = equest.POST.get('enmail') <--整列することでタイプミスに気づきやすい
email = request.POST.get('email')
url = request.POST.get('url')
3. 変数の羅列なども意味のある順番を選び、常にその順番に従う
大切なこと
- 一貫性のあるスタイルは「正しい」スタイルよりも大切
2.4 コメントすべきことを知る
できること
1. ひどい名前はコメントせずに名前自体を変える
2. コードの欠陥にコメントする
例:
// TODO : もっと高速なアルゴリズムを使う
// TODO : JPEG以外のフォーマットに対応する
2.5 コメントは正確で簡潔に
できること
1. コメントを簡潔にしておく
2. 曖昧な代名詞(それ、これ、あれ)を避ける
3. 関数の動作を正確に記述する
4. コードの意図を書く
プログラムの動作を高レベルから説明している例:
// 値段の高い順に表示する
for(list<Product>::reverse_interator it = products.rbegin(); ...)
大切なこと
1. コメントは領域に対する情報の比率が高くなければいけない
3 ループとロジックの単純化
3.1. 制御フローを読みやすくする
できること
条件式の引数の並び順
if(10 <= length) // 左: あまり変化しない 右:変化する
より
if(length >= 10) // 左: 変化する 右: あまり変化しない
if/elseブロックの並び順
・条件は否定形よりも肯定形を使う
・単純な条件を先に書く
・関心を引く条件や目立つ条件を先に書く
ネストを浅くする
3.2 巨大な式を分割する
できること
説明変数
以下のようなコードがあったとする
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){
//できない
}
3.3 変数と読みやすさ
できること
変数を削除する
役に立たない一時変数
中間結果を保持する変数
変数のスコープを縮める
グローバル変数はどこでどのように使われるのか追跡が難しかったり、ローカルの変数と衝突する可能性があるためグローバル変数は避けるべき
以下のsubmittedのようなグローバル変数は他のフィイルで使用されている可能性があるためコードを読む人を不安にさせる
submitted = false // グローバル変数
var submit_form = function(form_name) {
if(submitted){
return // 二重投稿禁止
}
...
submitted = true
}
以下のようにすることでグローバル変数を避けることができる
var submit_form = function() {
submitted = false
reuturn function (form_name) {
if(submitted){
return // 二重投稿禁止
}
}
...
submitted = true
}
大切なこと
- 変数を操作する場所が増えると現在地の判断が難しくなる
4 コードの再構成
4.1 無関係な下位問題を抽出する
できること
純粋なユーティリティーコード
文字列の操作、ハッシュテーブルの使用、ファイルの読み書きなどのプログラムの書くとなるタスクはライブラリで実装されているが、時に自身で新しい関数に置き換えるべき(ユーティリティコード)
汎用コードをたくさん作る
汎用コードはプロジェクトから完全に切り離されているため残りのコードが小さくなり考えやすくなる
やりすぎ
目標は「無関係の下位問題を積極的に見つけて抽出する」こと。だが積極的に見つけても、やりすぎたり、度を越したりする可能性もあるため注意する。
大切なこと
- プロジェクト固有のコードから汎用コードを分離する
4.2. 一度に一つのことを
できること
一度に一つのタスクをする
- コードが行なっている「タスク」を全て列挙する
- タスクをできるだけ異なる関数に分割する
大切なこと
- 関数は一度に一つのことを行うべき
4.3 コードに想いを込める
できること
ライブラリを知る
ライブラリ利用することで簡潔にコードを書くことができる
解決策を言葉で説明する
簡単な言葉で説明することでコードがより自然になる
説明で使用している単語やフレーズから下位問題の発見にもつながる
4.4 短いコードを書く
できること
コードを小さく保つ
・ユーティリティコードを作って重複コードを削除する
・未使用のコードや無用の機能を削除
身近なライブラリに親しむ
既存なライブラリで問題を解決できることもよくある
大切なこと
- 定期的に標準ライブラリ軽く読んでみることでどんなことができそうかを感じ取る
おわりに
今回「リーダブルコード」を拝読してみて初心者の自分でも今すぐにでも使っていけるようなテクニックも多くあり、とても勉強になりました。また、可愛い絵や面白いコマがあったり読み進めやすかったです。