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?

【リファクタリング】Extract Class(クラスの抽出)

0
Posted at

1. 概要(Overview)

Extract Class は代表的なリファクタリング手法の一つです。
あるクラスが肥大化し、複数の責務を抱え込んでいる(God Class 化しつつある) 場合、その一部のフィールドやメソッドを切り出して、新しいクラスとして独立させます。

Extract Class の目的は、責務を分割し、クラスごとの凝集度を高めることで、理解しやすく拡張しやすい設計にすることです。


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

  • クラスのコード量が増えすぎて、1,000行を超える巨大クラス になっている
  • クラスが 複数の概念や責務を同時に管理 している
  • 特定のフィールド群が、他のフィールドとは独立した振る舞いを持っている
  • あるメソッド群が、クラス全体ではなく 特定の役割だけを操作 している

よくある匂い:

  • Large Class(巨大クラス)
  • God Class(大泥棒)
  • Divergent Change(分岐的変更)

3. 手順(Mechanics / Steps)

  1. クラス内のフィールドやメソッドを観察し、まとまりを見つける
  2. 抽出対象のフィールドとメソッドを新しいクラスに移動
  3. 元クラスに新クラスのインスタンスを保持させる
  4. 呼び出しを新クラス経由に変更
  5. 不要になったコードを整理し、テストを実行

4. Kotlin 例(Before → After)

Before:責務を抱え込みすぎているクラス

class Person(
    val name: String,
    val age: Int,
    val street: String,
    val city: String,
    val zip: String
) {
    fun printProfile() {
        println("$name ($age)")
    }

    fun printAddress() {
        println("$street, $city, $zip")
    }
}
  • Person個人情報住所情報 を同時に管理
  • 責務が混ざっていて膨張しやすい

After①:Address クラスを抽出

class Address(
    val street: String,
    val city: String,
    val zip: String
) {
    fun printAddress() {
        println("$street, $city, $zip")
    }
}

class Person(
    val name: String,
    val age: Int,
    val address: Address
) {
    fun printProfile() {
        println("$name ($age)")
    }
}

Address を独立させることで責務が分離され、構造が明確に。


After②:段階的に移行(委譲メソッドを残す)

class Person(
    val name: String,
    val age: Int,
    private val address: Address
) {
    fun printProfile() {
        println("$name ($age)")
    }

    // 既存の呼び出しを壊さないため委譲
    fun printAddress() = address.printAddress()
}

→ 既存コードを壊さずに移行可能。


5. 効果(Benefits)

  • 責務が整理され、凝集度が高い小さなクラス に分割できる
  • コードが理解しやすくなり、保守・拡張が容易になる
  • 再利用性が向上(例:Address を他のエンティティでも利用可能)
  • 単体テストが簡単になり、テスト対象が明確化

6. 注意点(Pitfalls)

  • 抽出が細かすぎると、逆にクラスが増えすぎて管理が大変になる
  • 責務の境界が曖昧だと、どこまで抽出すべきか迷いやすい
  • 既存 API を公開している場合、委譲メソッド を残すなど互換性維持が必要

まとめ

  • Extract Class は「1つのクラスが持ちすぎた責務を分割する」リファクタリング
  • 判断基準:フィールドやメソッドに自然なまとまりがあるか?
  • 基本思想:責務を分けて、理解しやすく高凝集な設計にする

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?