Strategy パターン


Strategy パターンとは

一連のアルゴリズムを定義し、それぞれをカプセル化してそれらを交換可能にします。Strategyパターンによってアルゴリズムを使用するクライアントとは独立して、アルゴリズムを変更できます。

Strategyクラス

Listに含まれる重複を削除する方法を考える。重複削除のアルゴリズムをStrategyとしてカプセル化する。

public interface Strategy {
    List<String> unique(List<String> list);
}

StrategyImpl1ではSetに入れてからListにまた戻す方法。

public class StrategyImpl1 implements Strategy {
    @Override public List<String> unique(List<String> list) {
        return new ArrayList<String>((new HashSet<String>(list)));
    }
}

StrategyImpl2ではループでぐるぐる回す方法。

public class StrategyImpl2 implements Strategy {
    @Override public List<String> unique(List<String> list) {
        List<String> ret = new ArrayList<String>();
        for(String str : list) {
            if(!ret.contains(str)) ret.add(str);
        }
        return ret;
    }
}

Clientクラス

Clientでは外部から与えられるStrategyインターフェース経由で、重複削除の処理をStrategyに委譲。

public class Client {
    Strategy strategy;
    public Client(Strategy strategy) {
        this.strategy = strategy;
    }
    public int execute(List<String> list) {
        // 様々な処理
        return strategy.unique(list).size();
    }
}

テストコード

コンストラクタで重複削除のアルゴリズムを交換している。

    List<String> list = new ArrayList<String>();
    @Before public void setupList() {
        for(int i=0; i<1000000; i++) {
            list.add((i%100)+"");
        }
    }
    @Test public void test1() throws Exception {
        Client client = new Client(new StrategyImpl1());
        client.execute(list);
    }
    @Test public void test2() throws Exception {
        Client client = new Client(new StrategyImpl2());
        client.execute(list);
    }