Strategy パターン

「Strategy」という英単語は、「戦略」を意味します。ここで言う戦略とは、アルゴリズムの事を指します。

このパターンを適用すると、状況に応じた戦略に便宜変更することが容易となります。つまり、「Strategy」パターンとは、使用する側には意識させる事なく、柔軟に、また簡単に戦略(アルゴリズム)を切替えることを可能とするパターンです。


役割り

1. Strategy(戦略)
戦略のインタフェースを定義します。
2. ConcreteStrategyA・B(具体的戦略)の役

「Strategy」が定義したインタフェースを実装します。

具体的な戦略を作成します。

3. Context(状況判断)

状況により「ConcreteStrategy」を切替えその戦略を利用します。

利用するのは、あくまで「Strategy」で定義したメソッドです。

4. Client(利用者)
「Strategy」パターンを適用したクラスを用い処理を行います。

▲PageTop

クラス図

■ Strategyパターンのクラス図(1)

Strategyパターン クラス図(1)

■ Strategyパターンのクラス図(2) ※ファクトリー・パターンを用いた場合(オブジェクト生成判断処理を別クラスに切出し(使用者からの隠蔽))

Strategyパターン クラス図(2)

▲PageTop

サンプル

ソースコード

1. Strategy.java

public interface Strategy {
    public abstract String strategyMethod();
}

2-1. ConcreteStrategyA.java

public class ConcreteStrategyA implements Strategy {
    public String strategyMethod() {
        return "戦略A";
    }
}

2-2. ConcreteStrategyB.java

public class ConcreteStrategyB implements Strategy {
    public String strategyMethod() {
        return "戦略B";
    }
}

3. Context.java

public class Context {
    private Strategy strategy;
    public Context(Strategy strategy) {
        setStrategy(strategy);
    }
    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }
    public String contextMeshod() {
        return strategy.strategyMethod();
    }
}

4. Client.java

public class Client {
    public static void main(String[] args) {
        Context context = new Context(new ConcreteStrategyA());
        System.out.println(context.contextMeshod());
        context.setStrategy(new ConcreteStrategyB());
        System.out.println(context.contextMeshod());
    }
}

実行結果

C:\sample\desin_pattern\strategy\01>javac Client.java [Enter]

C:\sample\desin_pattern\strategy\01>java Client [Enter]
戦略A
戦略B
        

ソースコード(ファクトリー・パターンを用いた場合)

1. Strategy.java

public interface Strategy {
    public abstract String strategyMethod();
}

2-1. ConcreteStrategyA.java

public class ConcreteStrategyA implements Strategy {
    // ストラテジオブジェクトにIDを保持させる。オブジェクト生成するときの判断に使用する。
    public static final int ID = 1;
    public String strategyMethod() {
        return "戦略A";
    }
}

2-2. ConcreteStrategyB.java

public class ConcreteStrategyB implements Strategy {
    public static final int ID = 2;
    public String strategyMethod() {
        return "戦略B";
    }
}

3. Context.java

public class Context {
    private Strategy strategy;
    public Context(int id) {
        setStrategy(id);
    }
    public void setStrategy(int id) {
        // オブジェクト生成を「StrategyFactory」に切り出します。
        this.strategy = StrategyFactory.createStrategy(id);
    }
    public String contextMeshod() {
        return strategy.strategyMethod();
    }
}

4. Client.java

public class Client {
    public static void main(String[] args) {
        Context context = new Context(ConcreteStrategyA.ID);
        System.out.println(context.contextMeshod());
        context.setStrategy(ConcreteStrategyB.ID);
        System.out.println(context.contextMeshod());
    }
}

5. StrategyFactory.java

public class StrategyFactory {
    public static Strategy createStrategy(int id) {
        Strategy strategy = null;
        switch (id) {
        case ConcreteStrategyA.ID:
            strategy = new ConcreteStrategyA();
            break;
        case ConcreteStrategyB.ID:
            strategy = new ConcreteStrategyB();
            break;
        }
        return strategy;
    }
  }

実行結果(ファクトリー・パターンを用いた場合)

C:\sample\desin_pattern\strategy\02>javac Client.java [Enter]

C:\sample\desin_pattern\strategy\02>java Client [Enter]
戦略A
戦略B
        

▲PageTop