この記事のポイント

  • 三項演算子が適切に使われているかを読み取るレビュー力を鍛える
  • 冗長化・ネスト・副作用の危険を見抜く技術を整理する
  • 設計意図が表現されているかを読み取るレビューアーの視点を持つ

三項演算子は便利な短縮表現ですが、
設計が乱れ始める兆候が出やすいポイント でもあります。
レビューアーは「短く書いてある」ことに惑わされず、
意図の明確さ・読みやすさ を軸にレビューしたいところです。


1. 三項演算子とは? 使われる背景を整理する

三項演算子(条件演算子)は以下の形です。

cond ? expr1 : expr2

例えば:

int score = 85;
string grade = (score >= 80) ? "A" : "B";
  • 条件が単純な時は読みやすい
  • if-elseよりも1行で書ける

1-1. 使われやすい理由

  • 短く書けて気持ちいい
  • if-elseの段落分けが不要
  • ネストしても書けてしまう誘惑

1-2. だがレビューではここに着目する

  • 判定式は「設計意図の表現」である
  • 三項演算子は短縮のためではなく、比較的単純な条件用が適切
  • 複雑化・副作用混入・ネスト深掘りは危険信号

2. 良い利用例:レビュー合格パターン

int responseTimeMs = 120;

string status = (responseTimeMs < 100) ? "FAST" : "NORMAL";

cout << "Response status: " << status << endl;
  • 判定は閾値判定で単純
  • 条件内に副作用なし
  • 両側の表現も短い
  • if-else化するほどでもない内容

3. レビューアーが持つべきチェック観点

観点 チェック内容
条件式の複雑度 簡単に読める範囲内か?
ネスト 入れ子が無駄に深くないか?
副作用 評価内に状態更新を混ぜていないか?
左右の読みやすさ それぞれ短く読みやすい式か?
意図の明確さ 保守者が迷わず読めるか?
保守性 将来の拡張に耐えるか?

4. 良くない実装例:ケース別レビュー訓練

ケース1:ネスト化で読みにくくなる

struct ApiRequestLog {
    int requestId;
    string endpoint;
    int responseCode;
    string clientIp;
    string responseCategory;
};

void classifyResponse(ApiRequestLog& log) {
    log.responseCategory = (log.responseCode >= 500) ? 
                            ((log.responseCode >= 600) ? "CRITICAL" : "SERVER_ERROR") : 
                            ((log.responseCode >= 400) ? "CLIENT_ERROR" : "SUCCESS");
}
@Reviewer
ネストが深く可読性が落ちています。if-else構造に展開してください。

改善例

void classifyResponse(ApiRequestLog& log) {
    if (log.responseCode >= 600) {
        log.responseCategory = "CRITICAL";
    } else if (log.responseCode >= 500) {
        log.responseCategory = "SERVER_ERROR";
    } else if (log.responseCode >= 400) {
        log.responseCategory = "CLIENT_ERROR";
    } else {
        log.responseCategory = "SUCCESS";
    }
}

ネストが不要なら段階的にif-elseで整理する方が意図を伝えやすくなります。


ケース2:副作用混入で危険性上昇

bool isRequestValid(int requestId) {
    return requestId % 2 == 0;
}

void processRequest(ApiRequestLog& log) {
    log.responseCategory = (isRequestValid(log.requestId) ? "SUCCESS" : log.endpoint = "INVALID");
}
@Reviewer
三項演算子内に代入副作用を混入しています。条件文は純粋式に留め、副作用は分離してください。

改善例

void processRequest(ApiRequestLog& log) {
    if (isRequestValid(log.requestId)) {
        log.responseCategory = "SUCCESS";
    } else {
        log.endpoint = "INVALID";
        log.responseCategory = "FAILURE";
    }
}

副作用混入はレビュー対象として最優先で摘出してください。


ケース3:式評価が冗長で分かりにくい

string generateSummary(const ApiRequestLog& log) {
    return "Request: " + to_string(log.requestId) + " - " + 
        ((log.responseCode >= 400) ? "ERROR " + to_string(log.responseCode) : "OK");
}
@Reviewer
三項演算子内で文字列結合を複雑化させています。事前に分離してから組み立てましょう。

改善例

string generateSummary(const ApiRequestLog& log) {
    string status = (log.responseCode >= 400) ? "ERROR " + to_string(log.responseCode) : "OK";
    return "Request: " + to_string(log.requestId) + " - " + status;
}

ロジック単位で分けると保守もしやすくなります。


5. 観点チェックリスト


6. まとめ

三項演算子は便利ですが、
「短く書ける=良い」ではなく
「読みやすく意図が伝わるか」が判断基準 です。

レビューアーは

  • 短縮表現の誘惑に引きずられず
  • 設計意図が表現されているかを冷静に読む

この視点を持つことで、三項演算子のレビューは一段深くなります。
こうした読み方が自然にできると、レビュー全体の読み取り力も大きく伸びていきます。