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?

【リファクタリング】Form Template Method(テンプレートメソッドの形成)

Posted at

1. 概要(Overview)

Form Template Method は、
複数のメソッドの中に 似ている処理の流れ(アルゴリズムの骨格) が存在する場合に、
その共通部分をスーパークラスへ抽出し、テンプレートメソッドパターン を形成するリファクタリングです。

  • 共通の処理手順を スーパークラスのテンプレートメソッド として定義
  • 可変部分(サブクラスごとの差分)は 抽象メソッドやオーバーライド に分離

これにより、重複コードを削減し、アルゴリズムの枠組みを明確化 できます。

目的:

  • 重複コードの排除
  • アルゴリズムの構造を一元管理
  • 共通部分と可変部分を明確に分離

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

  • 複数のメソッドが 手順の流れは同じだが、一部だけ異なる
  • コードの重複が目立ち、メンテナンスが難しくなっている
  • 「アルゴリズムの共通骨格」と「差分の実装」を分けたい

よくある匂い:

  • Duplicate Code(重複コード)
  • Divergent Change(分岐的変更)

3. 手順(Mechanics / Steps)

  1. 類似するメソッドを比較して、共通手順と差分を特定
  2. 共通手順を スーパークラスのテンプレートメソッド として抽出
  3. 差分部分を 抽象メソッド/オーバーライド対象 として定義
  4. サブクラスで差分部分を実装
  5. テストを実行し、アルゴリズム全体が正しく動作することを確認

4. Kotlin 例(Before → After)

Before:重複した処理の流れ

class TextParser {
    fun parse(fileName: String): List<String> {
        val content = readFile(fileName)
        return content.split("\n").map { it.trim() }
    }

    private fun readFile(fileName: String): String {
        // ファイル読み込み処理
        return "line1\nline2"
    }
}

class CsvParser {
    fun parse(fileName: String): List<List<String>> {
        val content = readFile(fileName)
        return content.split("\n").map { it.split(",") }
    }

    private fun readFile(fileName: String): String {
        // ファイル読み込み処理
        return "a,b,c\n1,2,3"
    }
}
  • parse の冒頭処理(readFile 呼び出し)は同じ
  • 違うのは「読み込んだ後の処理部分」だけ

After:テンプレートメソッドを形成

abstract class Parser {
    fun parse(fileName: String): Any {
        val content = readFile(fileName)
        return transform(content)
    }

    protected fun readFile(fileName: String): String {
        // ファイル読み込み処理(共通)
        return "mock content"
    }

    // サブクラスごとに変わる部分
    protected abstract fun transform(content: String): Any
}

class TextParser : Parser() {
    override fun transform(content: String): List<String> {
        return content.split("\n").map { it.trim() }
    }
}

class CsvParser : Parser() {
    override fun transform(content: String): List<List<String>> {
        return content.split("\n").map { it.split(",") }
    }
}
  • 共通部分は Parser.parse() に集約
  • 可変部分は transform() としてサブクラスに委譲
  • 重複が消え、アルゴリズムの「枠組み」が明確になった

5. 効果(Benefits)

  • 重複コード削減 → メンテナンス性向上
  • アルゴリズムの構造が一箇所にまとまる → 理解しやすい
  • 新しいバリエーションの追加が容易(サブクラス追加だけで済む)

6. 注意点(Pitfalls)

  • 階層が増えるため、過剰に使うと 継承関係が複雑化
  • 共通化のために無理やり抽象化すると 可読性低下
  • 差分が大きすぎる場合は Template Method より Strategy パターン が適切

まとめ

  • Form Template Method は、複数のメソッドの「処理の流れの共通部分」をスーパークラスに抽出するリファクタリング
  • 判断基準:手順は同じで、処理の一部だけが異なっているか?
  • 基本思想:アルゴリズムの骨格を共通化し、差分はサブクラスに任せる

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?