このページでは、GoF(Gang of Four)によって提唱された23のデザインパターンの一つである「Template Methodパターン」について解説します。
このパターンは、アルゴリズムの骨組みを定義し、その一部の具体的な処理をサブクラスに委譲する設計手法です。
また、Java、C++、C#、VB.NETそれぞれの言語での実装サンプルを交えて、Template Methodパターンの使い方や利点について詳しく説明します。
Template Methodパターンとは
Template Methodパターンは、メソッドの骨組みをスーパークラスで定義し、処理の詳細をサブクラスに委ねるデザインパターンです。
これにより、コードの再利用性が高まり、拡張性が向上します。サブクラスで詳細な処理を定義することで、アルゴリズムの流れを変更せずに異なる動作を実現できます。
Template Methodパターンの使い方
Template Methodパターンは、共通のアルゴリズムを持つが、部分的な処理が異なる場合に有効です。
スーパークラスで共通部分を定義し、サブクラスで異なる処理を実装することで、コードの冗長さを削減しつつ、異なる動作を可能にします。
特に、同じプロセスの一部が変更されることが予想される場面に適しています。
Template Methodパターン実装サンプル
以下に、Java、C++、C#、VB.NETでのTemplate Methodパターンの実装サンプルを示します。
それぞれのサンプルコードにはコメントを付けて、各言語での実装のポイントを解説しています。
Javaでの実装サンプル
// Templateクラス(スーパークラス)
abstract class Game {
// Template Method
public final void play() {
initialize();
startPlay();
endPlay();
}
// サブクラスで定義する抽象メソッド
abstract void initialize();
abstract void startPlay();
abstract void endPlay();
}
// サブクラス1
class Football extends Game {
@Override
void initialize() {
System.out.println("Football Game Initialized! Start playing.");
}
@Override
void startPlay() {
System.out.println("Football Game Started. Enjoy the game!");
}
@Override
void endPlay() {
System.out.println("Football Game Finished!");
}
}
// サブクラス2
class Cricket extends Game {
@Override
void initialize() {
System.out.println("Cricket Game Initialized! Start playing.");
}
@Override
void startPlay() {
System.out.println("Cricket Game Started. Enjoy the game!");
}
@Override
void endPlay() {
System.out.println("Cricket Game Finished!");
}
}
// メインメソッドで実行
public class TemplateMethodPatternDemo {
public static void main(String[] args) {
Game game = new Football();
game.play();
System.out.println();
game = new Cricket();
game.play();
}
}
C++での実装サンプル
#include
using namespace std;
// Templateクラス(スーパークラス)
class Game {
public:
// Template Method
void play() {
initialize();
startPlay();
endPlay();
}
// サブクラスで定義する仮想関数
virtual void initialize() = 0;
virtual void startPlay() = 0;
virtual void endPlay() = 0;
};
// サブクラス1
class Football : public Game {
public:
void initialize() override {
cout << "Football Game Initialized! Start playing." << endl;
}
void startPlay() override {
cout << "Football Game Started. Enjoy the game!" << endl;
}
void endPlay() override {
cout << "Football Game Finished!" << endl;
}
};
// サブクラス2
class Cricket : public Game {
public:
void initialize() override {
cout << "Cricket Game Initialized! Start playing." << endl;
}
void startPlay() override {
cout << "Cricket Game Started. Enjoy the game!" << endl;
}
void endPlay() override {
cout << "Cricket Game Finished!" << endl;
}
};
// メイン関数で実行
int main() {
Game* game = new Football();
game->play();
cout << endl;
game = new Cricket();
game->play();
delete game;
return 0;
}
C#での実装サンプル
using System;
// Templateクラス(スーパークラス)
abstract class Game {
// Template Method
public void Play() {
Initialize();
StartPlay();
EndPlay();
}
// サブクラスで定義する抽象メソッド
protected abstract void Initialize();
protected abstract void StartPlay();
protected abstract void EndPlay();
}
// サブクラス1
class Football : Game {
protected override void Initialize() {
Console.WriteLine("Football Game Initialized! Start playing.");
}
protected override void StartPlay() {
Console.WriteLine("Football Game Started. Enjoy the game!");
}
protected override void EndPlay() {
Console.WriteLine("Football Game Finished!");
}
}
// サブクラス2
class Cricket : Game {
protected override void Initialize() {
Console.WriteLine("Cricket Game Initialized! Start playing.");
}
protected override void StartPlay() {
Console.WriteLine("Cricket Game Started. Enjoy the game!");
}
protected override void EndPlay() {
Console.WriteLine("Cricket Game Finished!");
}
}
// メインメソッドで実行
class Program {
static void Main(string[] args) {
Game game = new Football();
game.Play();
Console.WriteLine();
game = new Cricket();
game.Play();
}
}
VB.NETでの実装サンプル
' Templateクラス(スーパークラス)
Public MustInherit Class Game
' Template Method
Public Sub Play()
Initialize()
StartPlay()
EndPlay()
End Sub
' サブクラスで定義する抽象メソッド
Protected MustOverride Sub Initialize()
Protected MustOverride Sub StartPlay()
Protected MustOverride Sub EndPlay()
End Class
' サブクラス1
Public Class Football
Inherits Game
Protected Overrides Sub Initialize()
Console.WriteLine("Football Game Initialized! Start playing.")
End Sub
Protected Overrides Sub StartPlay()
Console.WriteLine("Football Game Started. Enjoy the game!")
End Sub
Protected Overrides Sub EndPlay()
Console.WriteLine("Football Game Finished!")
End Sub
End Class
' サブクラス2
Public Class Cricket
Inherits Game
Protected Overrides Sub Initialize()
Console.WriteLine("Cricket Game Initialized! Start playing.")
End Sub
Protected Overrides Sub StartPlay()
Console.WriteLine("Cricket Game Started. Enjoy the game!")
End Sub
Protected Overrides Sub EndPlay()
Console.WriteLine("Cricket Game Finished!")
End Sub
End Class
' メインメソッドで実行
Module Program
Sub Main()
Dim game As Game = New Football()
game.Play()
Console.WriteLine()
game = New Cricket()
game.Play()
End Sub
End Module
まとめ
Template Methodパターンは、アルゴリズムの骨組みを定義し、詳細な処理をサブクラスに委譲することで、再利用性と拡張性を高めるデザインパターンです。
Java、C++、C#、VB.NETそれぞれの実装サンプルを見ていただいたように、Template Methodパターンは多くのプログラミング言語で有効に機能します。
このパターンを使用することで、同じアルゴリズム内で異なる処理を容易に実装できるため、柔軟なシステム設計が可能になります。
