はじめに
Composing Methods とは、
「長すぎるメソッドや重複コードを小さく分割し、意図が明快で再利用可能なメソッド群に組み立て直すリファクタリング手法」を指します。
悪臭:「長すぎるメソッド」「重複コード」
解決策:Composing Methods
32.1 代表的なテクニック
1. Extract Method(メソッド抽出)
- まとまりのある処理を別メソッドに切り出す
- 「コメントで説明している部分」はメソッド化のサイン
2. Inline Method(メソッドのインライン化)
- 不要に分割されすぎたメソッドを統合
- 意味が薄い delegating method を削除
3. Extract Variable(変数抽出)
- 複雑な式を一時変数に置き換えて、読みやすくする
4. Inline Temp(変数のインライン化)
- 一時変数を直接式で置き換えることで冗長さを削除
5. Replace Temp with Query(変数を問い合わせに置換)
- 複雑な一時変数計算をメソッド化して再利用
6. Introduce Explaining Variable(説明変数の導入)
- 複雑な条件式を説明的な名前の変数にする
7. Replace Method with Method Object(メソッドをメソッドオブジェクトに置き換え)
- 長大なメソッドをクラス化して、変数やロジックを整理する手法
32.2 Kotlin 例
Before:長すぎるメソッド
fun printOwing(customer: Customer) {
var outstanding = 0.0
// ヘッダー表示
println("*************************")
println("***** Customer Owes *****")
println("*************************")
// 明細の計算
for (order in customer.orders) {
outstanding += order.amount
}
// フッター表示
println("name: ${customer.name}")
println("amount: $outstanding")
}
- 役割が混在 → 可読性が低い
- テストがしにくい
After:Extract Method で分割
fun printOwing(customer: Customer) {
printBanner()
val outstanding = calculateOutstanding(customer)
printDetails(customer, outstanding)
}
private fun printBanner() {
println("*************************")
println("***** Customer Owes *****")
println("*************************")
}
private fun calculateOutstanding(customer: Customer) =
customer.orders.sumOf { it.amount }
private fun printDetails(customer: Customer, outstanding: Double) {
println("name: ${customer.name}")
println("amount: $outstanding")
}
→ 各メソッド名が 「何をしているか」 を説明しており、コメント不要。
→ 処理の意図が明快になった。
32.3 実務での指針
- メソッドは10行以内 を目安に
- コメントで説明したくなる処理は Extract Method の候補
- 短いメソッドの集まりのほうが 再利用性・テスト容易性 が高い
- Kotlin では 拡張関数 も活用して Composing を進めやすい
まとめ
- Composing Methods はリファクタリングの基本ツール
- 長すぎるメソッド・重複コードを 小さなメソッド群に整理 する
- 基本思想:コードは短く、明快に、自己説明的に