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

デザインパターンとは IT技術
IT技術

デザインパターンは、ソフトウェア開発において頻繁に直面する設計上の問題を解決するためのテンプレートです。

GoF(Gang of Four)が提唱した23のデザインパターンの中で、「Strategyパターン」は、動的にアルゴリズムを選択できる柔軟な設計を実現します。

本記事では、Strategyパターンとは何か、その使い方やメリット、そしてJava、C++、C#での実装サンプルを通じて詳しく解説します。

Strategyパターンとは

Strategyパターンは、特定の機能やアルゴリズムの実装をクラスから分離し、必要に応じて動的に切り替えられるようにするデザインパターンです。

これにより、コードの再利用性が向上し、変更に強い柔軟な設計が可能となります。

Strategyパターンは、振る舞いを表現するために使用されます。

通常、あるクラスが持つメソッドの中でアルゴリズムを変更する必要がある場合、このパターンを利用します。アルゴリズムやロジックが複数あり、それらを切り替えたいときに特に有効です。

Strategyパターンのメリット

Strategyパターンを使用する主なメリットは、コードの保守性と拡張性の向上です。

アルゴリズムが独立しているため、コードの一部を変更することなく新しいアルゴリズムを追加することが容易になります。

また、依存関係を最小限に抑え、SRP(単一責任原則)を遵守することで、システムの柔軟性が向上します。

Strategyパターンの適用例

実際のプロジェクトでは、例えば支払い処理システムでクレジットカード、銀行振込、PayPalなど異なる決済方法を選択できるようにする場合にStrategyパターンが使われます。

ユーザーが決済方法を選ぶたびに、適切なアルゴリズムを実行できるように設計できます。

Strategyパターンの使い方

Strategyパターンの使い方は、アルゴリズムや処理を個別のクラスとして切り出し、それを使用するクラスに依存注入するというものです。

これにより、クラスの内部でアルゴリズムが変更されることはなく、利用する側が自由にアルゴリズムを選択できます。

まず、共通のインターフェースを定義し、各アルゴリズムクラスがそのインターフェースを実装します。

そして、Contextクラスにそのアルゴリズムを渡して実行します。これにより、動的なアルゴリズムの切り替えが可能になります。

Strategyパターンのクラス構成

Strategyパターンの基本的なクラス構成は以下の通りです。

Point
  • Strategyインターフェース:共通のアルゴリズムを定義するインターフェース。
  • 具体的なStrategyクラス:Strategyインターフェースを実装し、具体的なアルゴリズムを提供します。
  • Contextクラス:Strategyを利用するクラスで、動的にStrategyの実装を切り替えます。

Strategyパターン実装サンプル

ここでは、Strategyパターンの実装例をJava、C++、C#で紹介します。異なるプログラミング言語でも、基本的な設計は同じです。

共通のインターフェース(または抽象クラス)を使ってアルゴリズムを実装し、Contextクラスが動的にそのアルゴリズムを切り替えます。

JavaでのStrategyパターン実装例

JavaでのStrategyパターンの実装例は以下の通りです。

// Strategyインターフェース
public interface Strategy {
    public int doOperation(int num1, int num2);
}

// 具体的なStrategyクラス
public class OperationAdd implements Strategy {
    public int doOperation(int num1, int num2) {
        return num1 + num2;
    }
}

public class OperationSubtract implements Strategy {
    public int doOperation(int num1, int num2) {
        return num1 - num2;
    }
}

// Contextクラス
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 OperationSubtract());
        System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
    }
}

C++でのStrategyパターン実装例

C++でのStrategyパターンの実装例は以下の通りです。

// Strategyインターフェース
class Strategy {
public:
    virtual int doOperation(int num1, int num2) = 0;
};

// 具体的なStrategyクラス
class OperationAdd : public Strategy {
public:
    int doOperation(int num1, int num2) override {
        return num1 + num2;
    }
};

class OperationSubtract : public Strategy {
public:
    int doOperation(int num1, int num2) override {
        return num1 - num2;
    }
};

// Contextクラス
class Context {
private:
    Strategy* strategy;
public:
    Context(Strategy* strategy) : 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 OperationSubtract());
    std::cout << "10 - 5 = " << context->executeStrategy(10, 5) << std::endl;

    return 0;
}

C#でのStrategyパターン実装例

C#でのStrategyパターンの実装例は以下の通りです。

// Strategyインターフェース
public interface IStrategy {
    int DoOperation(int num1, int num2);
}

// 具体的なStrategyクラス
public class OperationAdd : IStrategy {
    public int DoOperation(int num1, int num2) {
        return num1 + num2;
    }
}

public class OperationSubtract : IStrategy {
    public int DoOperation(int num1, int num2) {
        return num1 - num2;
    }
}

// Contextクラス
public class Context {
    private IStrategy strategy;

    public Context(IStrategy 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 OperationSubtract());
        Console.WriteLine("10 - 5 = " + context.ExecuteStrategy(10, 5));
    }
}

まとめ

Strategyパターンは、アルゴリズムを動的に切り替えることで、ソフトウェア設計の柔軟性と保守性を高めるために非常に役立つパターンです。

Java、C++、C#などの異なるプログラミング言語においても、基本的な実装方法は共通しており、幅広い状況で応用可能です。

特にアルゴリズムが変更される場面が頻繁にあるプロジェクトでは、Strategyパターンを導入することで効率的な設計を実現できます。

タイトルとURLをコピーしました