1. 概要(Overview)
Introduce Parameter Object は、
メソッドに渡す 長い引数リスト(特に「いつも一緒に使われるデータの塊」)を、
オブジェクトとしてまとめて渡す ようにするリファクタリングです。
目的:
- 引数リストを短くして メソッド呼び出しをシンプルにする
- 関連データをひとまとまりにして 意味を明確にする
- データのまとまりにふさわしい 振る舞い(メソッド) を追加できる
2. 適用シーン(When to Use)
- メソッドの引数が多すぎる(3つ以上が目安)
- いつも同じセットの引数を一緒に渡している
- データの組み合わせが意味を持っている(例:日付の範囲、座標、個人情報など)
- 同じ引数の組み合わせが複数メソッドに渡されている
よくある匂い:
- Long Parameter List(長すぎる引数リスト)
- Data Clumps(いつも一緒に現れるデータの塊)
3. 手順(Mechanics / Steps)
- いつも一緒に渡されている引数群を特定
- それらをまとめる 新しいクラス(データクラス) を作成
- 新クラスをメソッドの引数に置き換える
- 呼び出し側を修正してオブジェクトを生成して渡す
- 必要ならそのオブジェクトに関連メソッドを追加する
4. Kotlin 例(Before → After)
4.1 単純な例:日付範囲
Before
fun getInvoices(startDate: LocalDate, endDate: LocalDate): List<String> {
println("Fetching invoices from $startDate to $endDate")
return emptyList()
}
val invoices = getInvoices(LocalDate.of(2025,1,1), LocalDate.of(2025,1,31))
After
data class DateRange(val start: LocalDate, val end: LocalDate)
fun getInvoices(range: DateRange): List<String> {
println("Fetching invoices from ${range.start} to ${range.end}")
return emptyList()
}
val invoices = getInvoices(DateRange(LocalDate.of(2025,1,1), LocalDate.of(2025,1,31)))
4.2 ビジネス例:顧客情報
Before
fun registerCustomer(name: String, email: String, phone: String) {
println("Registering $name, $email, $phone")
}
registerCustomer("Anna", "anna@example.com", "123-456")
After
data class CustomerInfo(val name: String, val email: String, val phone: String)
fun registerCustomer(info: CustomerInfo) {
println("Registering ${info.name}, ${info.email}, ${info.phone}")
}
registerCustomer(CustomerInfo("Anna", "anna@example.com", "123-456"))
4.3 発展:振る舞いを追加
data class DateRange(val start: LocalDate, val end: LocalDate) {
fun includes(date: LocalDate): Boolean = !date.isBefore(start) && !date.isAfter(end)
}
fun getInvoices(range: DateRange): List<String> {
if (!range.includes(LocalDate.now())) {
println("Warning: today is not in range")
}
return emptyList()
}
- 単なるデータの塊に ビジネスロジック を追加できる
5. 効果(Benefits)
- メソッド呼び出しが 短く明快になる
- 引数の組み合わせの意味が 型で表現される
- 将来的に関連ロジックをまとめやすい(ドメインオブジェクト化)
- 重複コード削減(毎回同じセットを渡す必要なし)
6. 注意点(Pitfalls)
- 過度に小さいデータまでオブジェクト化すると、クラス乱立で逆に複雑化
- そのオブジェクトが本当に「ひとまとまりの概念」かを見極める必要がある
- DTO(ただのデータ入れ物)に留まってしまい、中途半端な責務になる危険
まとめ
- Introduce Parameter Object は「いつも一緒に渡す引数群」を オブジェクトにまとめる リファクタリング
- 判断基準:引数のセットはひとつの概念として表せるか?
- 基本思想:引数を減らし、意味のある「オブジェクト」として再利用・拡張できるようにする