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?

【リファクタリング】Replace Inheritance with Delegation(継承の委譲への置き換え)

Posted at

1. 概要(Overview)

Replace Inheritance with Delegation は、
サブクラスがスーパークラスに 過剰に依存している、または継承関係が 不自然/誤用 されている場合に、
その継承をやめて 委譲(Delegation) に置き換えるリファクタリングです。

  • 継承:is-a 関係(例:Dog is an Animal)
  • 委譲:has-a 関係(例:Team has a Player)

誤った継承を委譲へ置き換えることで、結合度を下げ、柔軟性を高める ことができます。

目的:

  • 不自然な継承を取り除き、正しい関係へ修正
  • クラス間の結合度を下げ、変更に強くする
  • 再利用性・テスト容易性を高める

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

  • 継承しているが、本質的に is-a ではなく has-a の関係
  • サブクラスがスーパークラスの機能の一部しか使わない
  • サブクラスがスーパークラスの実装に強く依存し、変更に脆い
  • 将来的にスーパークラスの変更がサブクラスへ波及してしまうリスクがある

よくある匂い:

  • Refused Bequest(不要な継承)
  • Inappropriate Intimacy(不適切な親密さ)
  • Speculative Generality(過剰な一般化)

3. 手順(Mechanics / Steps)

  1. 継承関係が「不自然」か確認(is-a ではなく has-a か?)
  2. サブクラスにスーパークラスのインスタンスをフィールドとして保持
  3. サブクラス内で必要な処理を 委譲メソッド 経由で呼び出す
  4. スーパークラスの継承を削除
  5. テストを実行して、挙動が変わらないことを確認

4. Kotlin 例(Before → After)

Before:不自然な継承

// Stack が Vector を継承している(Java の古い実装例に近い)
class MyStack<E> : java.util.Vector<E>() {
    fun push(item: E) = this.add(item)
    fun pop(): E = this.removeAt(this.size - 1)
}
  • MyStackVector の全機能を継承してしまっている
  • しかしスタックは「Vector のすべての振る舞い」を持つべきではない
  • 本質的には Vector を内部で利用するだけ で十分

After:委譲へ置き換え

class MyStack<E> {
    private val data = mutableListOf<E>() // 委譲対象

    fun push(item: E) = data.add(item)

    fun pop(): E = data.removeAt(data.size - 1)

    fun isEmpty(): Boolean = data.isEmpty()
}
  • MyStackMutableListhas-a で保持
  • 本当に必要な操作だけを公開し、余計な機能は隠す
  • 結果、MyStack は「Vector ではなく Stack」であることが明確になる

5. 効果(Benefits)

  • 継承の誤用を防ぎ、責務が明確化
  • 内部実装を自由に差し替え可能(List → ArrayDeque 等)
  • サブクラスがスーパークラスに縛られなくなり、保守性・柔軟性が向上
  • 公開 API が必要最小限になり、誤用を防げる

6. 注意点(Pitfalls)

  • 委譲メソッドを多く定義する必要があり、コード量が増える可能性
  • 継承の方が自然な場合(真の is-a 関係)には逆効果
  • 過度に委譲を導入するとラッパークラスだらけになる(YAGNI を意識)

まとめ

  • Replace Inheritance with Delegation は、不自然な継承を「委譲」に置き換えるリファクタリング
  • 判断基準:その関係は本当に is-a か? それとも has-a か?
  • 基本思想:柔軟性・カプセル化を高め、依存関係を正しく整理する

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?