Strategyパターン
概要
このパターンはアルゴリズムをクラス化してクライアントからクラスの切り替えで処理を行うパターンになります。
クライアントからのアクセス用の共通メソッド(API)を用意してあげて、別々のクラスのメソッドにアクセスをして
完全に処理クラスに委譲することができます。
またこのパターンを利用するとContext内部でif else分などの条件文をすっきりさせることができます。
Strategyクラス
<?php //Strategy interface interface Strategy { public function calculate( array $array ); } //Strategy interfaceの実装 class SumCalculator implements Strategy { //計算の実行 public function calculate( array $data ) { $sum = 0; foreach( $data as $value ) { $sum += $value; } return $sum; } } //Strategy interfaceの実装 class MultiplyCalculator implements Strategy { //計算の実行 public function calculate( array $data ) { $sum = array_shift( $data ); foreach( $data as $value ) { $sum *= $value; } return $sum; } }
このように共通Interfaceを用いて計算処理を行う個別クラスにアルゴリズムを記述します。
Contextクラス
<?php // Strategyインスタンスを実行するContext class Subject { private function __construct(){} public static function calculate( Strategy $strategy, array $data ) { return $strategy->calculate( $data ); } }
ストラテジークラスのcalculate処理を呼び出すContextクラスを用意します。クライアントからはContextクラスを呼び出します。
client
<?php // client $data = array( 1, 2, 3, 4, 5); $val = Subject::calculate( new SumCalculator(), $data ); echo "$val \n"; $val = Subject::calculate( new MultiplyCalculator(), $data ); echo "$val \n";
クライアントからは何の処理を実行するかという情報を与えてあげるだけで済みます。
実行結果
15 120
その他使用例
以前紹介したvalidatorの処理が似ているかもしれません。
http://d.hatena.ne.jp/jogriko/20100923