はじめに
数ある コードの悪臭 の中で、最もよく見られるのが 重複コード と 長すぎるメソッド です。
これはまさに「万悪の根源」:
- 重複コード → 保守コストが増え、修正漏れの温床になる
- 長すぎるメソッド → 読みにくく、テストも困難
両者はしばしば同時に現れるため、代表的な解決策は メソッド抽出(Extract Method) です。
7.1 重複コード(Duplicated Code)
7.1.1 特徴:
- 同じ、または似たようなロジックが複数箇所に存在
- 要件変更時に、複数箇所を同時に修正する必要がある
7.1.2 解決手法
-
メソッド抽出(Extract Method)
-
クラス抽出(Extract Class)
-
テンプレートメソッドパターン
-
ユーティリティ化(共通モジュール化)
7.1.3 Kotlin 例 Before → After)
// Before
fun getDiscountedPrice(product: Product): Double {
return if (product.isMember) {
product.price * 0.9
} else {
product.price
}
}
fun getSpecialOfferPrice(product: Product): Double {
return if (product.isMember) {
product.price * 0.9
} else {
product.price
}
}
// After:共通メソッドに抽出
fun applyMemberDiscount(product: Product): Double {
return if (product.isMember) product.price * 0.9 else product.price
}
メリット:修正は1か所のみで済み、漏れを防げる。
7.2 長すぎるメソッド(Long Method)
7.2.1 特徴
- メソッドが数十行〜百行以上
- 複数の処理が混在していて読みにくい
- 多責務化 → 可読性の低下
- 再利用しにくい
7.2.2 解決手法
-
メソッド抽出(Extract Method)
-
説明変数導入(Introduce Explaining Variable)
-
ガード節(Guard Clauses)
-
ストラテジーパターン で条件分岐を外部に切り出す
7.2.3 Kotlin 例(Before → After)
// Before
fun checkout(order: Order) {
var subtotal = 0.0
for (item in order.items) {
subtotal += item.price
}
val tax = subtotal * 0.1
val discount = if (order.customer.level > 3) subtotal * 0.9 else subtotal
val total = discount + tax
println("Total: $total")
}
// After:メソッド抽出
fun subtotal(order: Order) = order.items.sumOf { it.price }
fun tax(amount: Double) = amount * 0.1
fun discount(customer: Customer, amount: Double) =
if (customer.level > 3) amount * 0.9 else amount
fun checkout(order: Order) {
val sub = subtotal(order)
val total = discount(order.customer, sub) + tax(sub)
println("Total: $total")
}
メリット:処理が整理され、再利用性・テスト容易性が高まる。
7.3 重複コードと長すぎるメソッドの関係
- 長すぎるメソッドは、同じロジックのコピペを生みやすい
- 重複コードが増えると、それをまとめて「長大なメソッド」に押し込めがち
メソッド抽出 が両方の共通解になる。
7.4 実務での指針
*「メソッドは 10 行以内」を目安(長くなる場合は役割ごとに分割)
-
重複検出ツールの活用:SonarQube / Detekt / IntelliJ Duplicate Detector
-
CI に Lint + 静的解析 を組み込み、自動で逸脱を可視化
-
早期リターン(ガード節)で ネストを浅く・読みやすく保つ
まとめ
- 重複コード:修正リスクが高い → 共通メソッドに抽出
- 長すぎるメソッド:読みにくい → 小さなメソッドに分割
- 基本思想:小さく明快なメソッド > 冗長で巨大なメソッド