1. 概要(Overview)
Form Template Method は、
複数のメソッドの中に 似ている処理の流れ(アルゴリズムの骨格) が存在する場合に、
その共通部分をスーパークラスへ抽出し、テンプレートメソッドパターン を形成するリファクタリングです。
- 共通の処理手順を スーパークラスのテンプレートメソッド として定義
- 可変部分(サブクラスごとの差分)は 抽象メソッドやオーバーライド に分離
これにより、重複コードを削減し、アルゴリズムの枠組みを明確化 できます。
目的:
- 重複コードの排除
- アルゴリズムの構造を一元管理
- 共通部分と可変部分を明確に分離
2. 適用シーン(When to Use)
- 複数のメソッドが 手順の流れは同じだが、一部だけ異なる
- コードの重複が目立ち、メンテナンスが難しくなっている
- 「アルゴリズムの共通骨格」と「差分の実装」を分けたい
よくある匂い:
- Duplicate Code(重複コード)
- Divergent Change(分岐的変更)
3. 手順(Mechanics / Steps)
- 類似するメソッドを比較して、共通手順と差分を特定
- 共通手順を スーパークラスのテンプレートメソッド として抽出
- 差分部分を 抽象メソッド/オーバーライド対象 として定義
- サブクラスで差分部分を実装
- テストを実行し、アルゴリズム全体が正しく動作することを確認
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 は、複数のメソッドの「処理の流れの共通部分」をスーパークラスに抽出するリファクタリング
- 判断基準:手順は同じで、処理の一部だけが異なっているか?
- 基本思想:アルゴリズムの骨格を共通化し、差分はサブクラスに任せる