0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【リファクタリング】Replace Error Code with Exception(エラーコードを例外に置き換える)

Posted at

1. 概要(Overview)

Replace Error Code with Exception は、メソッドの失敗を 戻り値(エラーコード) で表現する代わりに、
例外(Exception)をスローして通知するように変更するリファクタリングです。

エラーコード方式だと:

  • 呼び出し側が if (result == -1) のようなチェックを必ず書く必要がある
  • チェック漏れでバグを招きやすい
  • 戻り値が「成功値」と「エラー値」の両方に使われてしまう

例外に置き換えることで、エラー処理を明示的に分離でき、コードがシンプルになります。


2. 適用シーン(When to Use)

  • メソッドが 特殊な値(-1, null, error code) を返してエラーを表している
  • 呼び出し側でエラー判定が散在している
  • 「エラー処理」と「通常処理」が混ざって読みにくい

よくある匂い:

  • Error Handling Through Special Return Values(特殊値によるエラー処理)
  • Duplicated Conditional Logic(重複した条件分岐)

3. 手順(Mechanics / Steps)

  1. エラーを返す代わりに 例外クラスを定義
  2. メソッド内でエラー発生時に 例外をスロー
  3. 呼び出し側を修正し、戻り値チェック → try/catch に置き換え
  4. テストで正常系・異常系を確認

4. Kotlin 例(Before → After)

Before:エラーコードを返す

class Account(var balance: Int) {
    fun withdraw(amount: Int): Int {
        return if (amount > balance) {
            -1 // エラーコード
        } else {
            balance -= amount
            balance
        }
    }
}

fun main() {
    val account = Account(100)
    val result = account.withdraw(150)
    if (result == -1) {
        println("Insufficient funds")
    } else {
        println("New balance: $result")
    }
}

After:例外に置き換える

class InsufficientFundsException(message: String) : Exception(message)

class Account(var balance: Int) {
    fun withdraw(amount: Int): Int {
        if (amount > balance) {
            throw InsufficientFundsException("Insufficient funds: $amount > $balance")
        }
        balance -= amount
        return balance
    }
}

fun main() {
    val account = Account(100)
    try {
        val newBalance = account.withdraw(150)
        println("New balance: $newBalance")
    } catch (e: InsufficientFundsException) {
        println("Error: ${e.message}")
    }
}
  • エラーコード -1 を廃止し、InsufficientFundsException をスロー
  • 呼び出し側で try/catch によってエラー処理を分離できる

5. 効果(Benefits)

  • 通常処理とエラー処理を明確に分離できる
  • エラー処理の漏れを防ぎやすい(例外が伝播して検出される)
  • 戻り値を 本来の意味(成功値) に専念させられる
  • 呼び出しコードの可読性が向上

6. 注意点(Pitfalls)

  • 例外は「異常系」専用 → 「普通に起こりうる分岐」には使わない
    • 例:検索結果が存在しない → nullOptional の方が適切
    • 本当に「異常な状態(不正、資源不足)」なら例外
  • 過度な例外使用はパフォーマンスや可読性を下げる
  • 公開 API では「どの例外をスローしうるか」を明示すべき

まとめ

  • Replace Error Code with Exception は「特殊な戻り値でのエラー通知」をやめて、例外スローで明示化するリファクタリング
  • 判断基準:そのエラーは「正常系の一部」か「本当に異常」か?
  • 基本思想
    • 通常の制御フロー → 戻り値
    • 予期しないエラーや失敗 → 例外

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?