テンプレートメソッドパターン
CoddyのPythonジャーニー「Object Oriented Programming」セクションの一部 — レッスン 52/64。
Template Method パターンは、アルゴリズムのスケルトンを基底クラスで定義し、アルゴリズムの構造を変えることなく、特定のステップをサブクラスでオーバーライドできるようにするものです。
以下は、テンプレートメソッドを持つ基底クラスです:
class DataProcessor:
def process(self):
"""Template method defining the algorithm structure"""
self.read_data()
self.process_data()
self.save_data()
def read_data(self):
print("Reading data...")
def process_data(self):
raise NotImplementedError("Subclasses must implement this")
def save_data(self):
print("Saving data...")テンプレートメソッド process() はアルゴリズムのステップを定義し、一方で process_data() はサブクラスでの実装に委ねられています。
抽象メソッドを実装する具象クラスを作成します:
class CSVProcessor(DataProcessor):
def process_data(self):
print("Processing CSV data")
class JSONProcessor(DataProcessor):
def process_data(self):
print("Processing JSON data")各具象クラスは、必要なステップの独自の実装を提供します。
テンプレートメソッドを使用します:
csv_processor = CSVProcessor()
csv_processor.process()
print() # 空行
json_processor = JSONProcessor()
json_processor.process()ゲームのテンプレートを使用した別の例を作成します:
class Game:
def play(self):
"""Template method for playing a game"""
self.start_game()
self.play_game()
self.end_game()
def start_game(self):
print("Game started!")
def play_game(self):
raise NotImplementedError("Define the game rules")
def end_game(self):
print("Game ended!")
class Chess(Game):
def play_game(self):
print("Playing chess - thinking strategically...")
class Soccer(Game):
def play_game(self):
print("Playing soccer - running and kicking...")
chess = Chess()
chess.play()出力:
Reading data...
Processing CSV data
Saving data...
Reading data...
Processing JSON data
Saving data...
Game started!
Playing chess - thinking strategically...
Game ended!重要なポイント: Template Method パターンは、親クラスで共通のアルゴリズム構造を定義し、サブクラスに特定のステップをカスタマイズさせます。親クラスが全体のフローを制御しますが、サブクラスが具体的な実装を提供します。これにより、個々のステップに柔軟性を持たせつつ、一貫した構造を保証します。
チャレンジ
中級適切なカプセル化とメソッドを使用して、template.py と driver.py を実装してください。ステップバイステップのガイダンスについては、TODOコメントに従ってください。
チートシート
Template Method パターンは、アルゴリズムのスケルトンを基底クラスで定義し、アルゴリズムの構造を変えることなく、特定のステップをサブクラスでオーバーライドできるようにします。
テンプレートメソッドを持つ基底クラスを作成します:
class DataProcessor:
def process(self):
"""Template method defining the algorithm structure"""
self.read_data()
self.process_data()
self.save_data()
def read_data(self):
print("Reading data...")
def process_data(self):
raise NotImplementedError("Subclasses must implement this")
def save_data(self):
print("Saving data...")抽象メソッドを実装する具体的なクラスを作成します:
class CSVProcessor(DataProcessor):
def process_data(self):
print("Processing CSV data")
class JSONProcessor(DataProcessor):
def process_data(self):
print("Processing JSON data")テンプレートメソッドを使用します:
csv_processor = CSVProcessor()
csv_processor.process()
json_processor = JSONProcessor()
json_processor.process()Template Method パターンは、親クラスで共通のアルゴリズム構造を定義し、サブクラスで特定のステップをカスタマイズできるようにします。親クラスが全体のフローを制御し、サブクラスが具体的な実装を提供します。
自分で試してみよう
from template import Template
# テストケースのハンドラ
test_case = input()
if test_case == "basic_test":
# TODO: "Test Name" という名前で Template オブジェクトを作成する
# TODO: オブジェクトの display_info() メソッドを呼び出す
pass
elif test_case == "validation_test":
# TODO: "Validation Test" という名前で Template オブジェクトを作成する
# TODO: name プロパティを使用して、"Name: {obj.name}" という形式で名前を出力する
passこのレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。