戦略パターンの概念
戦略パターンは、一連のアルゴリズムを定義し、各アルゴリズムをカプセル化し、それらを交換可能にします。 Strategy パターンを使用すると、アルゴリズムを使用するクライアントとは独立してアルゴリズムを変更できます。
主な役割
抽象戦略の役割: Strategy クラス。通常はインターフェイスまたは抽象クラスによって実装されます。
戦略の具体的な役割: 関連するアルゴリズムと動作のパッケージ化。
環境ロール: 最終的にクライアントによって呼び出される戦略クラスへの参照を保持します。
アプリケーション シナリオ
1. 複数のクラスは、動作が異なるだけです。ストラテジー モードを使用すると、実行時に実行される特定の動作を動的に選択できます。
2. 状況に応じて異なる戦略 (アルゴリズム) を使用する必要があるか、将来的に戦略が別の方法で実装される可能性があります。
3. 特定の戦略 (アルゴリズム) の実装の詳細は顧客には隠されており、相互に完全に独立しています。
利点
1. 戦略パターンは、関連するアルゴリズム ファミリを管理する方法を提供します。ポリシー クラスの階層は、アルゴリズムまたは動作のファミリーを定義します。継承を適切に使用すると、共通のコードを親クラスに転送できるため、コードの重複を回避できます。
2. 戦略パターンは、継承関係を置き換える方法を提供します。継承は複数のアルゴリズムまたは動作を処理できます。戦略パターンを使用していない場合、アルゴリズムまたは動作を使用する環境クラスにはいくつかのサブクラスがあり、各サブクラスが異なるアルゴリズムまたは動作を提供する可能性があります。ただし、この方法では、アルゴリズムまたは動作のユーザーがアルゴリズムまたは動作自体と混同されます。どのアルゴリズムを使用するか、またはどの動作を実行するかを決定するロジックが、アルゴリズムや動作のロジックと混合され、独立して進化することができなくなります。継承により、アルゴリズムや動作を動的に変更することができなくなります。
3. ストラテジー モードを使用すると、複数の条件付き転送ステートメントの使用を回避できます。複数の転送ステートメントは保守が容易ではありません。どのアルゴリズムまたは動作を採用するかのロジックを 1 つの複数の転送ステートメントにまとめてリストします。これは継承方法よりも原始的で後進的です。 。
欠点
1. クライアントはすべてのポリシー クラスを理解し、どれを使用するかを決定する必要があります。これは、適切なタイミングで適切なアルゴリズム クラスを選択するために、クライアントがこれらのアルゴリズムの違いを理解する必要があることを意味します。言い換えれば、戦略パターンは、クライアントがすべてのアルゴリズムまたは動作を知っている場合にのみ適しています。
2. 戦略パターンは多くの戦略クラスを作成し、特定の戦略クラスごとに新しいクラスが生成されます。場合によっては、環境依存の状態をクライアントに保存することで、ポリシー クラスを共有可能に設計できるため、ポリシー クラスのインスタンスをさまざまなクライアントで使用できるようになります。つまり、フライウェイト パターンを使用してオブジェクトの数を減らすことができます。
戦略パターンの例
<?php/***策略模式*定义一系列的算法,把每一个算法封装起来,并且使它们可相互替换。*本模式使得算法可独立于使用它的客户变化*//***出行旅游*/interface TravelStrategy{ public function travelAlgorithm();}/***具体策略类(ConcreteStrategy)*1:乘坐飞机*/class AirPlanelStrategy implements TravelStrategy{ public function travelAlgorithm(){ echo"travelbyAirPlain","<BR>\r\n"; }}/***具体策略类(ConcreteStrategy)*2:乘坐火车*/class TrainStrategy implements TravelStrategy{ public function travelAlgorithm(){ echo"travelbyTrain","<BR>\r\n"; }}/***具体策略类(ConcreteStrategy)*3:骑自行车*/class BicycleStrategy implements TravelStrategy{ public function travelAlgorithm(){ echo"travelbyBicycle","<BR>\r\n"; }}/****环境类(Context):*用一个ConcreteStrategy对象来配置。*维护一个对Strategy对象的引用。可定义一个接口来让Strategy访问它的数据。*算法解决类,以提供客户选择使用何种解决方案:*/class PersonContext{ private$_strategy = null; public function __construct(TravelStrategy $travel){ $this->_strategy=$travel; } /** *旅行 */ public function setTravelStrategy(TravelStrategy $travel){ $this->_strategy=$travel; } /** *旅行 */ public function travel(){ return$this->_strategy->travelAlgorithm(); }}//乘坐火车旅行$person=new PersonContext(new TrainStrategy());$person->travel();//改骑自行车$person->setTravelStrategy(new BicycleStrategy());$person->travel();?>