1. 概要(Overview)
Inline Class は、役割が小さすぎて存在意義を失ったクラスを削除し、そのフィールドを元のクラスに戻す リファクタリングです。
これは Extract Class(クラスの抽出) の逆操作です。
以前は独立クラスとして分けたものの、十分な責務を持たず、かえって複雑さを増してしまった場合に適用します。
目的は以下の通りです:
- 不要な抽象化を取り除き、設計をシンプルに保つ
- クラスの数を減らして可読性を改善する
- 「存在価値のないクラス(Lazy Class)」を解消する
2. 適用シーン(When to Use)
- クラスが フィールドと getter/setter しか持たない
- 責務が薄く、ただのデータホルダーになっている
- クラスを導入したが、実際には他のクラスに統合した方が自然
- プロジェクトが進む中でクラスの存在意義がなくなった
よくある匂い:
- Lazy Class(怠惰なクラス)
- Speculative Generality(過剰な一般化)
3. 手順(Mechanics / Steps)
- 不要になったクラスを特定
- そのクラスのフィールドを元の利用クラスへ移動
- 呼び出しを修正して直接フィールドを利用するように変更
- 不要になったクラスを削除
- テストを実行して動作確認
4. Kotlin 例(Before → After)
Before:存在意義が薄いクラス
class Person(
val name: String,
val age: Int,
val telephoneNumber: TelephoneNumber
)
class TelephoneNumber(
val areaCode: String,
val number: String
)
-
TelephoneNumber
はただのデータ入れ物 - 振る舞いがなく、
Person
に統合しても問題ない
After:クラスをインライン化
class Person(
val name: String,
val age: Int,
val areaCode: String,
val number: String
)
→ TelephoneNumber
を削除し、フィールドを Person
に統合。
→ クラス数が減り、設計がシンプルに。
After②:一部メソッドがある場合も統合
class Person(
val name: String,
val age: Int,
val areaCode: String,
val number: String
) {
fun telephoneNumber(): String = "($areaCode) $number"
}
→ 元クラスにロジックを統合すれば、機能は維持できる。
5. 効果(Benefits)
- 不要な抽象化を削除 → 設計の単純化
- クラス数が減り → 理解・探索が容易
- Lazy Class を排除して 保守コストを削減
6. 注意点(Pitfalls)
- 将来拡張する可能性があるクラスは安易に削除しない
- クラス削除によって ドメインモデルの明確さが失われる 場合もある
- 「ただのデータホルダー」に見えても、ドメイン的に意味があるなら残す価値がある
まとめ
- Inline Class は「存在価値の薄いクラスを統合して削除する」リファクタリング
- 判断基準:そのクラスは本当に独立する意味があるか?
- 基本思想:過剰な一般化を排除し、シンプルで明快な設計にする