デザインパターン入門(Strategy)


この記事ではStrategyについてまとめます。
wikipediaによると「アルゴリズムを使用者から独立したまま様々に変化させることができるようになる」とあります。
参考:Strategyパターン

主な登場人物

NO 名前 役割
1 コンテキスト ストラテジをインスタンス化する
2 ストラテジ アルゴリズムのインタフェース
3 ストラテジの具象クラス アルゴリズムの実装

アルゴリズムを使用者から独立するとありますが、入れ替えが可能な処理群をインタフェースで隠蔽して細かくまとめる。必要であれば入れ替えることで影響範囲を局所化します。

パターンを実装する
駅で自動改札を利用する場合を想定して実装します。「非接触型ICカード(Suicaや、ICOCAなど)専用改札」「乗り換え専用改札」「切符専用改札」の3種類改札を通るという行為をStrategyパターンで実装します。

ストラテジ

Strategy.java
interface Strategy {
  void pass();
}

ストラテジの具象クラス

ConcreteNonContactTurnstile.java
class ConcreteNonContactTurnstile implements Strategy {
  public void pass() {
    System.out.println("Set And Touch!");
  }
}
ConcreteTicketTurnstile.java
class ConcreteTicketTurnstile implements Strategy {
  public void pass() {
    System.out.println("Ticket accept");
  }
}
ConcreteTransferTurnstile.java
class ConcreteTransferTurnstile implements Strategy  {
  public void pass() {
     System.out.println("Transfer Line!");
  }
}

コンテキスト

ContextStation.java
class ContextStation {
  Strategy strategy;

  public ContextStation(Strategy strategy) {
    this.strategy = strategy;
  }

  public void pass() {
    strategy.pass();
  }
}

実行クラス

Main.java
class Main {
  public static void main(String[] args) {
    ContextStation contextStation;
    contextStation = new ContextStation(new ConcreteNonContactTurnstile());
    contextStation.pass();
  }
}
結果
Set And Touch!

上記の通り、類似した処理群を1つのインターフェスを実装する形で抽象化します。そのインタフェースへの参照を保持するコンテキストという役割のクラス経由でストラテジ以下のクラスをインスタンス化しています。実装時には、メインクラスの「new ContextStation(new Concrete○○)」の○○部分を入れ替えることで処理内容を高速に変更することがこのパターンの目的です。新しい種類の改札「有人改札」を追加する場合には新規ストラテジの具象クラスを追加して、前述したパターンの部分を入れ替えることで実装できます。