概要
**Template Method Pattern(テンプレートメソッドパターン)**は、
処理の枠組み(フレームワーク)を固定し、可変部分をサブクラスに委ねる設計パターンである。
不変な処理の流れと、変更可能な処理のポイントを明確に分離し、
拡張性と秩序を同時に担保する構造をもたらす。
本稿では、Pythonの継承機構と抽象メソッドを活用した実装例とともに、
このパターンの真価が発揮されるユースケースを解説する。
1. なぜテンプレートメソッドか?
❌ サブクラスが全体の処理順序まで定義してしまう
class Report:
def generate(self):
self.fetch_data()
self.format()
self.export()
→ 各サブクラスで generate()
を書き直すと 処理順序がばらばらになり品質低下
✅ テンプレートメソッドで「流れ」だけ親クラスに定義
from abc import ABC, abstractmethod
class ReportGenerator(ABC):
def generate(self):
data = self.fetch_data()
formatted = self.format(data)
self.export(formatted)
@abstractmethod
def fetch_data(self): ...
@abstractmethod
def format(self, data): ...
@abstractmethod
def export(self, content): ...
→ 処理の「流れ」は固定され、可変ポイントだけを明示的に実装可能
2. 実装例:CSVとJSONのレポート生成
class CSVReport(ReportGenerator):
def fetch_data(self):
return [{"id": 1, "name": "Alice"}]
def format(self, data):
return ",".join(data[0].keys()) + "\n" + ",".join(map(str, data[0].values()))
def export(self, content):
print("Exporting CSV:\n" + content)
class JSONReport(ReportGenerator):
def fetch_data(self):
return {"id": 1, "name": "Bob"}
def format(self, data):
import json
return json.dumps(data)
def export(self, content):
print("Exporting JSON:\n" + content)
report = JSONReport()
report.generate()
3. フックメソッドによる柔軟性の追加
class ReportGenerator(ABC):
def generate(self):
self.before()
data = self.fetch_data()
formatted = self.format(data)
self.export(formatted)
self.after()
def before(self): pass
def after(self): pass
→ before()
/ after()
を任意オーバーライド可能なフックポイントとして提供
4. 実務ユースケース
✅ テストフレームワークの構造化
class TestCase:
def run(self):
self.setup()
self.execute()
self.teardown()
def setup(self): pass
def execute(self): raise NotImplementedError
def teardown(self): pass
→ ユーザーは execute()
だけを実装すればよく、テストの流れは崩れない
✅ データパイプラインの統一的設計
class DataPipeline:
def run(self):
raw = self.extract()
transformed = self.transform(raw)
self.load(transformed)
def extract(self): raise NotImplementedError
def transform(self, data): raise NotImplementedError
def load(self, data): raise NotImplementedError
5. よくある誤用と対策
❌ サブクラスがテンプレートメソッドを上書きする
→ ✅ generate()
などテンプレートメソッドは 最終形として親に固定すべき
→ Pythonでは慣習的に # Do not override
コメントを付けることもある
❌ インタフェースと実装が混在し拡張不能
→ ✅ ABC
+ abstractmethod
によって 設計意図を明示的に表現
結語
Template Method Pattern は、処理手順の「骨格」は変えず、局所的な実装を柔軟に差し替える設計思想である。
- サブクラスは「何をするか」に集中し、「いつ・どの順で行うか」は親が制御
- ソフトウェアの振る舞いをテンプレートとして固定することで、秩序と自由を両立
- フレームワーク、データ処理、テスト基盤など、あらゆるレイヤーで活用可能
Pythonicとは、“振る舞いをオープンに、構造を堅牢に”設計することであり、
Template Method はその哲学を、継承という仕組みで最も明確に表現する構造である。