はじめに
前回に引き続き,デザインパターンを扱っていきます.
今回は,Strategyパターンに焦点を当てていきます.
GoFデザインパターンのオブジェクトの振る舞いに関するものとなります.
Strategyパターンとは?
Strategyパターンは,アルゴリズムを表すインタフェースを定義して,
このインタフェースから派生したクラスを作成し,
アルゴリズムを実行時には作成したクラスの中から選んで実行することができる
デザインパターンです.
これにより,たくさんのアルゴリズムが再利用できますし,変更に対して柔軟に対応することができます.
基本的な構成は以下のようになります.
ここで,Strategyはアルゴリズムを実装する際の共通のインタフェースです.
Contextは呼び出し元がどのアルゴリズムを使用するか決定する際に呼び出すクラスです.
具体例
ある数値を並び替えて出力する場合を考えてみます.
このとき,「並び替える」という行動がアルゴリズムを表すインタフェースとして定義できます.
そして,並び替える手段は,昇順か降順の2つだけ考えます.
(もちろん,もっと複雑な場合を考えるのが通常です)
すると,以下のような構造にすべきだと考えられます.
この構造を参考にしてソースコードを作ったものが以下となります.
import java.util.List;
public interface SortStrategy {
void sort(List<Integer> numbers);
}
import java.util.Collections;
import java.util.List;
public class AscendingSort implements SortStrategy {
@Override
public void sort(List<Integer> numbers) {
Collections.sort(numbers);
}
}
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());
}
}
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.");
}
}
}
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パターンは使いやすそうなデザインパターンだと感じたので,
機会があればぜひ使っていきたいです.