Strategyパターンは、異なるアルゴリズムを動的に切り替えられるデザインパターンの一つです。このパターンは、GoF (Gang of Four) によって提唱され、特に動作の変更が必要な際に柔軟な設計を可能にします。この記事では、Strategyパターンの概要、使い方、そしてJava、C++、C#、VB.NETでの実装サンプルを通じて、具体的な利用方法を解説します。
Strategyパターンとは
Strategyパターンは、アルゴリズムを個別のクラスにカプセル化し、クライアントの要求に応じて異なるアルゴリズムを動的に切り替えられるようにするデザインパターンです。
このパターンを使用することで、同じクライアントで異なる処理を柔軟に実行できるため、コードの再利用性が向上し、保守性も高まります。
例えば、同じ計算処理でも、異なるアルゴリズムで計算したい場合にStrategyパターンを使用します。
Strategyパターンの使い方
Strategyパターンの主な構成要素は以下の3つです:
Strategyインターフェース
実行可能なアルゴリズムを定義します。
ConcreteStrategyクラス
具体的なアルゴリズムを実装するクラスです。
Contextクラス
クライアントが利用するクラスで、Strategyインターフェースを利用してアルゴリズムを実行します。
これらを使って、異なるアルゴリズムを動的に切り替える設計を実現できます。
Strategyパターン実装サンプル
以下では、Java、C++、C#、VB.NETそれぞれでのStrategyパターンの実装例を示します。
各コードには簡単なコメントも付加していますので、各言語での使い方を確認してください。
Javaの実装サンプル
public interface Strategy {
public int doOperation(int num1, int num2);
}
public class OperationAdd implements Strategy {
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
public class OperationSubstract implements Strategy {
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public int executeStrategy(int num1, int num2) {
return strategy.doOperation(num1, num2);
}
}
public class StrategyPatternDemo {
public static void main(String[] args) {
Context context = new Context(new OperationAdd()); // 足し算を選択
System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationSubstract()); // 引き算を選択
System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
}
}
C++の実装サンプル
#include
class Strategy {
public:
virtual int doOperation(int num1, int num2) = 0;
};
class OperationAdd : public Strategy {
public:
int doOperation(int num1, int num2) override {
return num1 + num2;
}
};
class OperationSubstract : public Strategy {
public:
int doOperation(int num1, int num2) override {
return num1 - num2;
}
};
class Context {
private:
Strategy* strategy;
public:
Context(Strategy* strategy) {
this->strategy = strategy;
}
int executeStrategy(int num1, int num2) {
return strategy->doOperation(num1, num2);
}
};
int main() {
Context* context = new Context(new OperationAdd());
std::cout << "10 + 5 = " << context->executeStrategy(10, 5) << std::endl;
context = new Context(new OperationSubstract());
std::cout << "10 - 5 = " << context->executeStrategy(10, 5) << std::endl;
return 0;
}
C#の実装サンプル
using System;
interface Strategy {
int DoOperation(int num1, int num2);
}
class OperationAdd : Strategy {
public int DoOperation(int num1, int num2) {
return num1 + num2;
}
}
class OperationSubstract : Strategy {
public int DoOperation(int num1, int num2) {
return num1 - num2;
}
}
class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public int ExecuteStrategy(int num1, int num2) {
return strategy.DoOperation(num1, num2);
}
}
class Program {
static void Main(string[] args) {
Context context = new Context(new OperationAdd());
Console.WriteLine("10 + 5 = " + context.ExecuteStrategy(10, 5));
context = new Context(new OperationSubstract());
Console.WriteLine("10 - 5 = " + context.ExecuteStrategy(10, 5));
}
}
VB.NETの実装サンプル
Public Interface Strategy
Function DoOperation(ByVal num1 As Integer, ByVal num2 As Integer) As Integer
End Interface
Public Class OperationAdd
Implements Strategy
Public Function DoOperation(ByVal num1 As Integer, ByVal num2 As Integer) As Integer Implements Strategy.DoOperation
Return num1 + num2
End Function
End Class
Public Class OperationSubstract
Implements Strategy
Public Function DoOperation(ByVal num1 As Integer, ByVal num2 As Integer) As Integer Implements Strategy.DoOperation
Return num1 - num2
End Function
End Class
Public Class Context
Private strategy As Strategy
Public Sub New(ByVal strategy As Strategy)
Me.strategy = strategy
End Sub
Public Function ExecuteStrategy(ByVal num1 As Integer, ByVal num2 As Integer) As Integer
Return strategy.DoOperation(num1, num2)
End Function
End Class
Module Module1
Sub Main()
Dim context As New Context(New OperationAdd())
Console.WriteLine("10 + 5 = " & context.ExecuteStrategy(10, 5))
context = New Context(New OperationSubstract())
Console.WriteLine("10 - 5 = " & context.ExecuteStrategy(10, 5))
End Sub
End Module
まとめ
Strategyパターンは、異なるアルゴリズムを動的に切り替える際に非常に有効なデザインパターンです。
これにより、柔軟性と保守性の高いコードを実現することができます。
本記事では、Java、C++、C#、VB.NETでの実装例を通して、Strategyパターンの基本的な概念とその活用方法を説明しました。
このパターンを利用することで、コードの再利用性を高め、アルゴリズムを容易に変更可能にすることができます。
