#概要
研究過程を経てやはり良いコードであると開発スピード/品質が高まると強く感じたので、どうすれば良いコードになるか改めて勉強した。
教材は教授からお勧めしていただいたリーダブルコード( https://www.oreilly.co.jp/books/9784873115658/ )を読み、本記事では自分のためにもざっくりまとめました。
#1.良いコードの定義
他人が理解するのにかかる時間が短い
#2.表面上の改善
- 変数や関数の名前に情報を詰め込む
教材にはない教授から教えて頂いた方法
関数名:動詞-目的語(例) getPage(url) )
変数名:修飾語-名詞(例) memorySize or mem_size )
- tmpやretvalなどの汎用的な名前は避ける
- tmpはswap時などに使えるなので「一時保存以外に役割がない」ことを示す
- retvalにはこれは戻り値です以外の情報はない
- 変数の目的や値を表すものがいい名前
2乗の合計が帰ってくるならばretval ではなく sum_squares
- ループイテレータについて
例) i,j,kではなく
club[i].members[j].user[k] × => club[club_i].members[members_i].user[users_i]
- 値の単位を明示する
例) 単位がミリ秒 => var start_ms = (new Date()).getTime();
他) size => size_mb , limit -> max_kbps
- なるべく長い変数名はよくない
- これまでのテクニックの否定になりそうだが、そうではなく変数が見えるスコープが小さいなら多くの情報を詰める必要はないということである。
if(debug){
map{string,int}m;
insert(&m);
Print(&m);
}
insert(&m)やPrint(&m)のmがグローバル変数やクラスのメンバ変数ならmの目的がよく分からないので良くない
スコープが限定されたところだけ上の例ならif()~内でしか使われないなら簡素な変数名でもOK
- (大事)途中から新しいメンバが入ってきても理解できる変数
例) BackEndManagerを略してBEManagerとして伝わるか-> 否
- googleはクラスのメンバ変数の最後に**「_」**をつけ,すぐにローカル変数と区別できるようにしているらしい
class LogReader{
private:
int offset_;
}
- 変数に危険や注意を喚起する情報を追加
例) これからエスケープが必要な変数には前に「raw_」をつける
#3.誤解されない名前
- 範囲指定するときは[start,stop]x -> [first,last] or [max,min]
- bool型の変数は頭に「is,has,can」
#4.美しさ
- (当たり前だが)見た目を美しくするとそのままコードの簡潔さ・拡張性につながる
- タブなどを使って変数などの縦の線を揃える
- メゾットや変数は分けてブロックで一塊にする(役割によってサブブロックを作っても良い)
例)
class TestClass{
public:
//変数ブロック
//サブブロック:data
int id;
int wight;
int height;
//サブブロック:flag
int isPublish;
.
.
//メゾットブロック
//サブブロック:handle method
void checkOption();
.
.
//サブブロック:database
void insert();
}
- 一貫性を保つ
- 次の二つのうちのどちらなのか
class Test{
};
class
{
};
#5.コメントすべきことを知る
- コードをすぐみたらわかることはコメントにしない
- コードを書いているときに持っている大切な考えをコメントとして記載する
- コメントとして書くもの(代表例)
コメント | 意味 |
---|---|
ToDo | あとで手をつける |
FIXME | 既知の不具合があるコード |
HACK | あまりきれいじゃない解決策 |
XXX | 危険 大きな問題がある |
- 定数の値を設定するに至った背景をコメントする
#6.コメントは正確で簡潔に
- あいまいになるため,コメント中は代名詞を使わない
- 名前付き引数コメントにする
例) connetct(10,false) x -> connect(timeout =10,use_encry = false)
※ cやjavaの場合 connet(/*timeout =*/10,/*use_encry =*/ false)
- 関数の動作はできるだけ正確に説明する
- コードの意図は詳細レベルではなく高レベルで記述
#7.ループとロジックの単純化
- 制御フローを分かり易くする
- 条件式の並び順
例) if(bytes_extected > bytes_received)よりもif(bytes_received < bytes_extected)の方が良い
**左側:**調査対象の式で変化する **右側:**比較の対象であまり変化しない
-
行数を短くするのも良いがそれよりも優先すべきは,他人が理解するのにかかる時間を短くすること
- 例えばif/elseを使わず三項演算子を使った方が行数が少なくなるが分かりづらくなることもある
-
早めに返してネストを削除する=なるべくネストの深さを減らす工夫をする
- 理由:if文内にさらにif文があったりすると,ネストが増え次のelse文にいくまでに値などを忘れてしまう
-
if/else文の条件は一般的に肯定形・単純・目立つものを先に処理する
#おわりに
今回は書籍の約1/3をざっくりまとめたので、残りの2/3もまとめて後日記事として投稿する
##おまけ
書籍内には下記の書籍もいくつか紹介/推奨していた
- Code Complete 第2版<上><下>-完全なプログラミングを目指して-
- リファクタリング-プログラムの体質改善テクニック
- プログラミング作法
- 達人プログラマー - システム開発の職人から名匠への道
- Clean Code-アジャイルソフトウェア達人の技