39
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

よくあるコーディングスタイル改善パターン

Last updated at Posted at 2015-10-02

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 を使うのはやめよう。

39
34
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
39
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?