1. 概要(Overview)
Self Encapsulate Field とは、
クラスのフィールドへのアクセスを 直接参照 から アクセサ(getter/setter)経由 に変更するリファクタリングです。
目的:将来的にフィールドアクセスへ ロジックや制約を追加 できるようにすること。
2. 適用シーン(When to Use)
- フィールドに直接アクセスしているが、今後ロジックを追加する可能性がある
- サブクラスや外部クラスに影響を与えずに アクセス制御や処理を挟みたい
- Lazy Load, Validation, Logging などをフィールド参照に組み込みたい
3. 手順(Mechanics / Steps)
- 対象フィールドに対応する getter/setter を作成
- クラス内部のフィールド参照を、すべて getter/setter 経由に変更
- 必要に応じて getter/setter に 追加ロジック(検証・変換・通知など) を実装
4. Kotlin 例(Before → After)
Before:フィールドを直接参照
class Thermostat {
var temperature: Int = 20
fun increase() {
temperature += 1
}
fun decrease() {
temperature -= 1
}
}
-
temperatureに直接アクセスしている - 将来的に 制約(例:0℃以下禁止) を加えるのが難しい
After:Self Encapsulate Field
class Thermostat {
private var _temperature: Int = 20
var temperature: Int
get() = _temperature
set(value) {
require(value >= 0) { "温度は0℃未満にできません" }
_temperature = value
}
fun increase() {
temperature = temperature + 1
}
fun decrease() {
temperature = temperature - 1
}
}
→ フィールドを getter/setter 経由 に切り替え。
→ 不変条件(0℃未満禁止)を安全に導入できるようになった。
5. 効果(Benefits)
- 将来的に 制約やロジックを容易に追加可能
- サブクラスでオーバーライドして挙動を拡張できる
- フィールドアクセスを 統一インターフェース にできる
- 外部利用者に影響を与えずに内部実装を変更できる
6. 注意点(Pitfalls)
- 単純に「getter/setter を増やすだけ」だと冗長化する
- Kotlin の場合は
val/varのプロパティ構文 があるため、過剰に使うと Java 的冗長コードになる - 本当に必要な場合だけ 適用する(将来の変更が見込まれる箇所など)
まとめ
- Self Encapsulate Field はフィールドへの直接参照を getter/setter に置き換えるリファクタリング
- メリット:将来的な 拡張性・安全性 を確保できる
- 基本思想:データアクセスは必ず「窓口」を通すことで、制御と柔軟性を得る