2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Strategyパターン

Last updated at Posted at 2025-01-01

はじめに

前回に引き続き,デザインパターンを扱っていきます.

今回は,Strategyパターンに焦点を当てていきます.

GoFデザインパターンのオブジェクトの振る舞いに関するものとなります.

Strategyパターンとは?

Strategyパターンは,アルゴリズムを表すインタフェースを定義して,
このインタフェースから派生したクラスを作成し,
アルゴリズムを実行時には作成したクラスの中から選んで実行することができる
デザインパターンです.

これにより,たくさんのアルゴリズムが再利用できますし,変更に対して柔軟に対応することができます.

基本的な構成は以下のようになります.

ここで,Strategyはアルゴリズムを実装する際の共通のインタフェースです.

Contextは呼び出し元がどのアルゴリズムを使用するか決定する際に呼び出すクラスです.

スクリーンショット 2025-01-01 180143.png

具体例

ある数値を並び替えて出力する場合を考えてみます.

このとき,「並び替える」という行動がアルゴリズムを表すインタフェースとして定義できます.

そして,並び替える手段は,昇順か降順の2つだけ考えます.
(もちろん,もっと複雑な場合を考えるのが通常です)

すると,以下のような構造にすべきだと考えられます.

スクリーンショット 2025-01-01 180706.png

この構造を参考にしてソースコードを作ったものが以下となります.

SortStrategy.java
import java.util.List;

public interface SortStrategy {
    void sort(List<Integer> numbers);
}
AscendingSort.java
import java.util.Collections;
import java.util.List;

public class AscendingSort implements SortStrategy {
    @Override
    public void sort(List<Integer> numbers) {
        Collections.sort(numbers);
    }
}

DescendingSort.java
import java.util.Collections;
import java.util.List;

public class DescendingSort implements SortStrategy {
    @Override
    public void sort(List<Integer> numbers) {
        Collections.sort(numbers, Collections.reverseOrder());
    }
}
Sorter.java
import java.util.List;

public class Sorter {
    private SortStrategy strategy;

    public void setStrategy(SortStrategy strategy) {
        this.strategy = strategy;
    }

    public void sort(List<Integer> numbers) {
        if (strategy != null) {
            strategy.sort(numbers);
        } else {
            throw new IllegalStateException("Sort strategy is not set.");
        }
    }
}
Main.java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>(Arrays.asList(5, 2, 8, 1, 3));

            
        Sorter sorter = new Sorter();

        // 昇順ソート
        sorter.setStrategy(new AscendingSort());
        System.out.println("Before sorting (ascending): " + numbers);
        sorter.sort(numbers);
        System.out.println("After sorting (ascending): " + numbers);

        // 降順ソート
        sorter.setStrategy(new DescendingSort());
        sorter.sort(numbers);
        System.out.println("After sorting (descending): " + numbers);
    }
}
出力例
Before sorting (ascending): [5, 2, 8, 1, 3]
After sorting (ascending): [1, 2, 3, 5, 8]
After sorting (descending): [8, 5, 3, 2, 1]

このようにアルゴリズム部分が共通のインタフェースを持つようにしたことで,
数値を別の方法で並び替えたいとなったときに,SortStrategyをインタフェースとして
新たにファイルを追加するだけで新たな並び替え方法を追加することができます.

さらに,ソースコードを修正する際にもどこを修正すればよいかがわかりやすいです.

Strategyパターンにより要件の変更や追加に対して強い設計になりました.

最後に

Strategyパターンを使うことによって,コードの可読性やメンテナンスを容易にすることができます.

Strategyパターンは使いやすそうなデザインパターンだと感じたので,
機会があればぜひ使っていきたいです.

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?