はじめに
Organizing Data は、
「データ構造やフィールドの扱いを整理し、設計を改善するためのリファクタリング手法群」です。
目的は:
- データの意味を明確化する
- 重複や不整合をなくす
- 可読性・保守性を高める
多くのコードの悪臭(Primitive Obsession, Data Clumps, Duplicate Data など)に対応する「基盤的リファクタリング」が揃っています。
代表的なテクニック
1. Self Encapsulate Field(フィールドの自己カプセル化)
- フィールドに直接アクセスせず、getter/setter 経由に変更
- 将来的に制約やロジックを追加しやすくなる
2. Replace Data Value with Object(データ値をオブジェクトに置換)
- 単なる値(例:電話番号、金額)をクラスに置き換え、意味とルールを持たせる
3. Replace Array with Object(配列をオブジェクトに置換)
- 配列のインデックス依存をやめ、名前付きフィールドを持つオブジェクトに変換
4. Replace Magic Number with Symbolic Constant(魔法の数値を定数に置換)
- 意味不明なリテラル値を名前付き定数に置き換える
5. Encapsulate Collection(コレクションのカプセル化)
- コレクションを直接公開せず、追加・削除メソッドを経由させる
6. Replace Record with Data Class(レコードをデータクラスに置換)
- フィールドの集合をデータクラスにまとめ、表現力を高める
7. Replace Type Code with Class / Subclass / State/Strategy
- 「種類コード」を enum / クラス / サブクラスに置き換える
Kotlin 例
Before:プリミティブ執着
class Order(val customerName: String, val customerPhone: String)
- 電話番号はただの
String - フォーマットやバリデーションは呼び出し側に散らばる
After:Replace Data Value with Object
@JvmInline
value class PhoneNumber(val value: String) {
init {
require(value.matches(Regex("\\d{2,4}-\\d{2,4}-\\d{4}"))) {
"不正な電話番号形式: $value"
}
}
}
class Order(val customerName: String, val customerPhone: PhoneNumber)
→ 電話番号の妥当性チェックを 型に閉じ込める。
→ 呼び出し側の責務が減り、表現力が向上。
実務での指針
- 小さすぎるデータクラスを作りすぎると逆に複雑化
- 過剰な抽象化は避ける(YAGNI 原則:You Aren’t Gonna Need It)
- チームで「どの程度プリミティブを置き換えるか」を共通ルール化するとよい
まとめ
- Organizing Data はデータ設計を整理するリファクタリング群
- 対応する匂い:Primitive Obsession / Data Clumps / Duplicate Data
- 基本思想:データは「型」に責務を持たせ、正しい場所に整理する