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 Parameter with Method Call(引数をメソッド呼び出しに置き換え)

Posted at

1. 概要(Overview)

Replace Parameter with Method Call は、
呼び出し側で計算済みの値や外部から渡されたパラメータを使う代わりに、
その値をメソッドの内部で直接取得する ように変更するリファクタリングです。

目的

  • 呼び出し側から「余計な計算」や「不要な情報渡し」を取り除く
  • API のシンプル化(引数の削減)
  • データ取得の責務を呼び出し側ではなくオブジェクト自身に持たせる

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

  • 引数として渡される値が、呼び出し側で計算しているだけのもの
  • メソッド内で すでに同じ情報を取得可能
  • 「呼び出し側が本来知るべきでない情報」を引数にしている

よくある匂い:

  • Long Parameter List(長すぎる引数リスト)
  • Inappropriate Intimacy(不適切な親密さ:外部に余計な情報を求めている)
  • Feature Envy(呼び出し側が本来持つべきでないロジックを持っている)

3. 手順(Mechanics / Steps)

  1. パラメータがどのように算出されているか確認
  2. その値を呼び出し側ではなく、対象オブジェクト自身が計算できるかを検討
  3. メソッドの引数から不要なパラメータを削除
  4. メソッド内部で必要な計算や呼び出しを実装
  5. 呼び出し側を修正し、冗長な計算を取り除く

4. Kotlin 例(Before → After)

4.1 顧客の割引(呼び出し側で計算)

Before

class Customer(val orders: List<Int>) {
    fun getDiscountPrice(orderCount: Int): Int {
        return if (orderCount > 5) 100 else 0
    }
}

fun main() {
    val customer = Customer(listOf(10, 20, 30))
    val discount = customer.getDiscountPrice(customer.orders.size) // 呼び出し側で size を計算
    println(discount)
}

After

class Customer(val orders: List<Int>) {
    fun getDiscountPrice(): Int {
        val orderCount = orders.size
        return if (orderCount > 5) 100 else 0
    }
}

fun main() {
    val customer = Customer(listOf(10, 20, 30))
    val discount = customer.getDiscountPrice() // スッキリ!
    println(discount)
}

4.2 日付の比較(呼び出し側で取得 → メソッド内部へ)

Before

class Subscription(val startDate: LocalDate, val endDate: LocalDate)

fun isActive(subscription: Subscription, today: LocalDate): Boolean {
    return today.isBefore(subscription.endDate)
}

val sub = Subscription(LocalDate.now(), LocalDate.now().plusDays(30))
println(isActive(sub, LocalDate.now())) // today を毎回渡す必要がある

After

class Subscription(val startDate: LocalDate, val endDate: LocalDate) {
    fun isActive(): Boolean {
        val today = LocalDate.now()
        return today.isBefore(endDate)
    }
}

val sub = Subscription(LocalDate.now(), LocalDate.now().plusDays(30))
println(sub.isActive()) // 呼び出し側がシンプルに!

5. 効果(Benefits)

  • 呼び出しコードが短く、意図が明確になる
  • パラメータリストを減らせる(API がシンプルになる)
  • 呼び出し側に不要な知識(内部データや計算方法)を持たせなくてよい
  • 変更に強くなる(内部の計算方法が変わっても呼び出し側は影響を受けない)

6. 注意点(Pitfalls)

  • 内部で取得できない情報(外部入力や利用者依存のデータ)は削除できない
  • 内部での計算コストが大きい場合、呼び出し側でキャッシュした方が効率的なケースもある
  • 責務の所在が曖昧にならないよう注意(「どこで計算すべきか」を設計レベルで判断)

まとめ

  • Replace Parameter with Method Call は「呼び出し側で計算・取得して渡している値」を、
    メソッド内で直接取得するように変えるリファクタリング
  • 判断基準:呼び出し側が知るべきでない情報を渡していないか?
  • 基本思想:値を知っている責務を持つオブジェクトに計算を移し、API をシンプルに保つ

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?