1. 概要(Overview)
Remove Assignments to Parameters は、メソッドの引数(パラメータ)に対して再代入しているコードを修正するリファクタリングです。
パラメータは「呼び出し側から渡された値」であり、関数の入力として扱うべきものです。再代入を行うと、コードの意図が不明確になり、思わぬバグを引き起こす可能性があります。
目的は以下の通りです:
- パラメータを不変(immutable)な入力として扱う
- 副作用を減らし、コードの安全性を高める
- 意図を明確にし、保守性を向上させる
2. 適用シーン(When to Use)
- メソッドのパラメータが 途中で再代入されている
- パラメータの再代入が「計算用の一時変数」として使われている
- 呼び出し元に副作用がないにもかかわらず、再代入によって誤解を招く
よくある匂い:
- Side Effects(副作用)
- Obscure Intent(意図の不明確さ)
3. 手順(Mechanics / Steps)
- 再代入されているパラメータを確認
- 再代入をやめて、新しいローカル変数を導入
- 参照箇所をすべて新しい変数に切り替える
- テストを実行して正しく動作することを確認
4. Kotlin 例(Before → After)
Before:パラメータに再代入している
fun discount(price: Double, rate: Double): Double {
var rateVar = rate
if (rateVar > 0.5) {
rateVar = 0.5
}
return price * (1 - rateVar)
}
-
rateパラメータに直接代入している(rateVarを別名で使っているケースもNG) - 呼び出し側は「渡した値が書き換えられるのか?」と誤解する可能性がある
After①:ローカル変数を導入
fun discount(price: Double, rate: Double): Double {
val effectiveRate = if (rate > 0.5) 0.5 else rate
return price * (1 - effectiveRate)
}
→ rate は入力値として不変のまま扱い、再代入用の変数を別に導入。
After②:さらにシンプルに
fun discount(price: Double, rate: Double): Double {
return price * (1 - rate.coerceAtMost(0.5))
}
→ Kotlin の標準関数を使えば、より明確で安全に。
5. 効果(Benefits)
- 入力パラメータの不変性を保証し、コードの意図が明確になる
- 副作用の誤解を減らし、バグのリスクを下げる
- ロジックがシンプルになり、テストもしやすくなる
- 関数型プログラミングの「入力は不変」という考え方に沿った設計になる
6. 注意点(Pitfalls)
- 古いコードや一部の言語では「パラメータに再代入して書き換える」スタイルが一般的に使われていることがある(移行時に注意)
- 大規模リファクタリングでは、一気に変えると混乱を招くため、段階的に適用するのが安全
- 再代入を除去する際は、適切な変数名を付けて「意図」を残すことが重要
まとめ
- Remove Assignments to Parameters は「パラメータを不変に保ち、副作用をなくす」リファクタリング
- 判断基準:その再代入は入力として適切か? それとも計算用の変数か?
- 基本思想:パラメータは呼び出し元から渡された「入力値」であり、変更してはいけないもの