C やそれに類する構文を持つ命令型言語用。
If-else 条件の逆転 (1)
If 節の中身が else 節の中身より長い場合、条件と if/else の中身を逆にした方が普通は読みやすい。
// いまいちな例
if (foo) {
doSomething1();
doSomething2();
// やたら長い正常系処理...
doSomethingN();
} else {
logError("..."); // 短い異常系処理
}
// マシになった例
if (!foo) {
logError("..."); // 短い異常系処理
} else {
doSomething1();
doSomething2();
// やたら長い正常系処理...
doSomethingN();
}
If-else 条件の逆転 (2)
Else 節の中身が return, break, continue, goto で終わるが if 節はそうでない場合、条件と if/else の中身を逆にした方が普通は読みやすい。
// いまいちな例
if (foo) {
doSomething1();
} else {
doSomething2();
return;
}
doSomething3();
// マシになった例
if (!foo) {
doSomething2();
return;
} else {
doSomething1();
}
doSomething3();
さらにこの後、以下の「Else 節からの取り出し (1)」を適用することができる。
// さらにマシになった例
if (!foo) {
doSomething2();
return;
}
doSomething1();
doSomething3();
Else 節からの取り出し (1)
If 節の中身が return, break, continue, goto で終わるときは、else 節の中身を if-else 文の外に出すことでインデントを減らすことができる。
// いまいちな例
if (foo) {
doSomethingX();
return;
} else {
doSomethingElse1();
doSomethingElse2();
// やたら長い else の中身...
doSomethingElseN();
}
// 改善例
if (foo) {
doSomethingX();
return;
}
doSomethingElse1();
doSomethingElse2();
// やたら長い else の中身...
doSomethingElseN();
Else 節からの取り出し (2)
If-else 文の直後に return, break, continue, goto がある場合は、それを if 節の最後にも置くことで同様に else 節の中身を外に出すことができる。
// いまいちな例
if (!foo) {
logError("..."); // 短い異常系処理
} else {
doSomething1();
doSomething2();
// やたら長い正常系処理...
doSomethingN();
}
return;
// 改善例
if (!foo) {
logError("..."); // 短い異常系処理
return;
}
doSomething1();
doSomething2();
// やたら長い正常系処理...
doSomethingN();
return;
関数の末尾の if 文
関数の末尾に else 節のない if 文がある場合は、条件を逆にして return することで if 文の中身を if 文の外に出してインデントを減らすことができる。
// いまいちな例
void foo() {
...
if (bar) {
doSomething1();
doSomething2();
// やたら長い処理...
doSomethingN();
}
}
// 改善例
void foo() {
...
if (!bar) {
return;
}
doSomething1();
doSomething2();
// やたら長い処理...
doSomethingN();
}
ループの末尾の if 文
ループの末尾に else 節のない if 文がある場合は、条件を逆にして continue することで if 文の中身を if 文の外に出してインデントを減らすことができる。
// いまいちな例
while (foo) {
...
if (bar) {
doSomething1();
doSomething2();
// やたら長い処理...
doSomethingN();
}
}
// 改善例
while (foo) {
...
if (!bar) {
continue;
}
doSomething1();
doSomething2();
// やたら長い処理...
doSomethingN();
}
一致個所の共通化
If 節と else 節の中身がほとんど同じ場合は、違うところだけを if-else 文内に残して、後は外に出す。コードを読む人に人力で diff を取らせるべからず。
// いまいちな例
if (foo) {
this.listView.bounds = newBounds(top, right, bottom + normalMargin, left);
} else {
this.listView.bounds = newBounds(top, right, bottom + wideMargin, left);
}
// 改善例
float bottomMargin;
if (foo) {
bottomMargin = normalMargin;
} else {
bottomMargin = wideMargin;
}
this.listView.bounds = newBounds(top, right, bottom + bottomMargin, left);
// さらに if 文をやめて ? : 演算子にすると
float bottomMargin = foo ? normalMargin : wideMargin;
this.listView.bounds = newBounds(top, right, bottom + bottomMargin, left);
Do-while ではなく while や for を使う
ループの先頭にループの条件が書かれている方が、普通は読みやすい。「ループが 1 回以上回ることは最初からわかっているから」という理由だけで for や while ではなく do-while を使うのはやめよう。