Strategyパターンとは | GoFデザインパターン

記事内に広告が含まれています。

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パターンの基本的な概念とその活用方法を説明しました。

このパターンを利用することで、コードの再利用性を高め、アルゴリズムを容易に変更可能にすることができます。

オブジェクト指向プログラミングにおけるGoFの23のデザインパターン
デザインパターンは、ソフトウェア設計の問題を効果的に解決するための再利用可能な解決策です。本記事では、GoF(Gang ...
タイトルとURLをコピーしました