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?

【リファクタリング】第25回 不適切な親密さ(Inappropriate Intimacy)

Posted at

はじめに

不適切な親密さ(Inappropriate Intimacy) とは、
2つのクラスが互いの内部に 過度に依存・干渉 している状態を指します。

例:

  • AクラスがBクラスの内部フィールドに直接アクセス(getter 連発など)
  • 双方向参照があり、どちらかを変更するともう一方も必ず修正が必要
  • 本来は疎結合であるべき層(Domain ↔ Infrastructure)が強く結びついている

カプセル化違反 であり、テスト・保守・再利用を難しくします。


25.1 特徴

  • クラスが他クラスの詳細に強く依存している
  • getter/setter 経由で相手クラスのデータを頻繁に操作
  • 双方向の参照が存在し、依存が複雑化
  • 境界(レイヤーやモジュール)が崩壊している

25.2 解決手法

  • メソッド移動(Move Method)
    → 相手クラスのデータを頻繁に操作する処理は、利用している側ではなくそのクラスへ移動
  • フィールド移動(Move Field)
    → 本来属すべきクラスにフィールドを移動
  • 仲介の導入(Introduce Mediator / Facade)
    → 双方向依存を避け、中間クラスを設ける
  • 依存方向の整理(Dependency Inversion, Clean Architecture)
    → 下位層 → 上位層への依存を逆転させ、境界を明確にする

25.3 Kotlin 例

Before:不適切な親密さ

class Customer(val name: String, val address: Address)

class Address(var street: String, var city: String) {
    fun updateFromCustomer(customer: Customer) {
        // Customer の情報に直接依存
        println("Updating address for ${customer.name}")
    }
}
  • AddressCustomer の内部に依存
  • 双方向に近い結合 → 修正時に影響が拡大

After①:責務を移動

class Customer(val name: String, val address: Address) {
    fun updateAddress(street: String, city: String) {
        address.update(street, city)
        println("Updated address for $name")
    }
}

class Address(var street: String, var city: String) {
    fun update(street: String, city: String) {
        this.street = street
        this.city = city
    }
}

Customer が責務を持つことで、AddressCustomer に依存しなくなった。


After②:仲介役を導入

class AddressUpdater {
    fun update(customer: Customer, street: String, city: String) {
        customer.address.update(street, city)
        println("Updated address for ${customer.name}")
    }
}

class Customer(val name: String, val address: Address)
class Address(var street: String, var city: String) {
    fun update(street: String, city: String) {
        this.street = street
        this.city = city
    }
}

CustomerAddress の直接的な親密さを Updater で調整。


25.4 実務での指針

  • 双方向依存は極力避ける(依存方向を一方通行に)
  • getter 連発は「親密さのサイン」 → メソッド移動で解消
  • 境界を越えるアクセスが多い場合は Mediator / Facade / DTO を導入
  • Clean Architecture / DDD を適用して 層の責務を整理

まとめ

  • Inappropriate Intimacy は「2つのクラスがべったり結合」している悪臭
  • 解決策は Move Method / Move Field / Mediator / Dependency Inversion
  • 基本思想クラス間の距離は適度に保つ。疎結合こそ健全な設計

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?